HOWTO · React
在 React 中將 props 傳遞給子元件
了解 React 如何透過 props.children 渲染巢狀內容,以及 Context 或 React.cloneElement() 如何讓子內容使用額外的值。
本頁內容
React 元件可以透過 props.children 顯示巢狀在標籤之間的內容。顯示這些內容並不會自動將 props 加到其中的元素。若要將值提供給後代元件,請使用 Context;若要將 prop 加到一個已知的子元素,請使用 React.cloneElement()。
例如,訊息對話框可能會收到文字、表情符號,或由多個元素組成的內容。可重複使用的元件不必事先知道內容是什麼,只要在對話框內文應出現的位置顯示 props.children 即可。
在 React 中將 props 傳遞給子元件
包裝元件可以在標記中回傳 {children},以顯示巢狀內容。例如,function Box({ children }) { return <div>{children}</div>; } 會顯示父元件放在 <Box> 與 </Box> 之間的內容。父元件可以像這樣組合子元件:function App() { return <Box><Text /></Box>; }。
這種組合會將 Text 元素作為 children prop 傳給 Box,但不會替 Text 設定 color prop。如果子元件需要某個值,可以在建立子元件時明確傳入,例如 <Text color="red" />;如果包裝元件需要提供該值,也可以使用以下其中一種方法。
以下 JSX 片段用來說明元件如何組合,並假設應用程式中已有 React;它們不是可獨立執行的檔案,也不是實際執行結果。子元件可以透過類似 function Text({ color }) { return <p style={{ color }}>Welcome to App</p>; } 的函式簽章讀取這個值。
使用 Context API 在 React 中將 props 傳遞給子元件
如果子樹中的多個元件需要相同的值,而逐層傳遞會造成不必要的程式串接,可以使用 Context。Context 會讓提供者下方的消費者取得某個值;它與 props 不同,也不會真的將 prop 逐一傳過每個元件。
先建立一個 Context,例如 const ColorContext = React.createContext("black");,再將提供者放在需要該值的內容外層:<ColorContext.Provider value="red">{children}</ColorContext.Provider>。後代元件可以透過 const color = React.useContext(ColorContext); 讀取該值,並像這樣套用:<p style={{ color }}>Welcome to App</p>。提供者的值會提供給在該提供者內呈現的元件,因此請確保提供者涵蓋需要該值的子樹。只有當消費者上方沒有相符的提供者時,才會使用預設值。如果存在相符的提供者,消費者會收到提供者傳入的值,即使該值是 undefined,也不會改用預設值。
如果多個後代元件都會使用某個值,例如主題或語系,這種方法就很合適。若只有一個子元件需要額外的單一值,複製元素可能更直接。
使用 React.cloneElement() 在 React 中將 props 傳遞給子元件
React.cloneElement() 會根據有效的 React 元素和一組 props 建立新元素。包裝元件可以使用 React.cloneElement(children, { color: "red" }),在一個子元素上新增或覆寫 color,同時保留子元素的其他 props。接著,子元件就能像上方的 Text 範例一樣使用 color。
此方法預期 children 是一個有效的 React 元素。props.children 也可能是文字、多個元素或其他形狀,因此呼叫 React.cloneElement() 前,請先檢查或以其他方式處理其形狀;不能把任意文字或多個子元素當成單一元素傳入這個單元素形式。如果包裝元件需要接受不同形式的內容,可以原樣呈現內容;如果後代元件需要共用同一個值,則可使用 Context。
若要在整個子樹中使用某個值,請選擇 Context。若包裝元件需要刻意修改一個已知的子元素,請選擇 React.cloneElement()。這兩種方法都不會改變 props.children 的基本用途:它代表父元件提供的巢狀內容。