iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0

上篇文章中介紹了如何使用 Container/Presentational Pattern 來實作通用的 <Table> 元件,並且把資料管理和選擇邏輯分離到容器元件中。今天則要來討論 Compound Pattern~

什麼是 Compound Pattern?

我自己的理解是,Compound Pattern 適合用於父元件內包含多個子元件的情境,且這些子元件需要根據不同狀態或邏輯動態顯示或隱藏時。使用 Compound Pattern 可以很自由地挑選出要出現的子元件,而且能保持清晰的結構與邏輯。

先提一個比較好理解的例子:

一個簡單的卡片元件範例

以下是一個簡單的卡片元件 <Card>

// 元件的架構被固定住,無法靈活地調整卡片的內容或結構
export default function Card(props) {
	return (
		<div>
			<h2>{props.title}</h2>
			<p>{props.content}</p>
			<button>Read More</button>
		</div>
	);
}

這樣的寫法雖然簡單,但問題在於當我們希望卡片元件可以在不同情境下顯示不同內容(例如不同的標題、描述、按鈕)時,我們必須在 Card 元件內進行修改或增加大量的 props,這樣會讓元件變得難以維護。

使用 Compound Pattern 改善結構

為了讓這個卡片元件能夠更靈活地控制其內部的結構,我們可以使用 Compound Pattern。這樣做可以讓父元件 <Card> 提供一個上下文(Context),允許我們在子元件中選擇性地使用不同的內容組合。

使用 Compound Pattern 改寫的範例:

  1. 首先,我們使用 Context API 創建一個 CardContext 以提供共享的狀態:
import { createContext } from 'react';

const CardContext = createContext();

const Card = ({ children }) => {
  return <CardContext.Provider value={{}}>{children}</CardContext.Provider>;
};
  1. 接著定義幾個子元件來表示卡片的不同部分:
const CardTitle = ({ children }) => <h2>{children}</h2>;
const CardContent = ({ children }) => <p>{children}</p>;
const CardButton = ({ children }) => <button>{children}</button>;
  1. 最後,可以在父元件 <Card> 中,自由地組合這些子元件來構建卡片的結構:
const App = () => {
  return (
    <Card>
      <CardTitle>自訂的標題</CardTitle>
      <CardContent>這是卡片的內容。</CardContent>
      <CardButton>了解更多</CardButton>
    </Card>
  );
};

export default App;

這樣,我們就可以根據需要隨意組合卡片的內容,而不需要更改父元件或子元件的程式碼。這就是 Compound Pattern 的強大之處!

實務上常見的使用情況

Compound Pattern 的文章中,有特別提到這樣的設計模式很適合用在 select、dropdown、menu items 上,舉例來說可能是:

  • 選單(Menu)或下拉選單(Dropdown Components)
  • 選擇(Select)元件
  • 導航標籤(Tabs)
  • 手風琴(Accordion)
  • 表單組件(Form Components)

補充:

  • 為什麼使用 Context 來取得狀態?

    在 React 中,父元件與子元件間的資料傳遞通常是透過 props 完成的,這很適合單純的元件結構。然而,當一個應用程式的層級變得較為複雜時,例如某個深層的子元件需要使用父元件的某個狀態,就需要一層一層地傳遞 props,這就是所謂的 prop drilling 問題。

    Context 提供了一種解決方案,它允許我們將狀態存在一個「上下文」中,這樣任何需要使用這個狀態的子元件都可以直接透過 useContext 來取得,而無需經過每一層元件傳遞 props

參考資料


上一篇
Day 9 - 透過 Container/Presentational Pattern 來實現功能與樣式分離
下一篇
Day 11 - SOLID 原則在 React 的實踐(一)
系列文
剛入行就一人重新打造公司前端系統?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
harry xie
iT邦研究生 1 級 ‧ 2024-09-18 16:24:10

目前系列文看到這邊,都蠻清楚好懂,期待大大補充內容

我要留言

立即登入留言