?
This document uses PHP Chinese website manual Release
React具有強大的組合模型,我們推薦使用組合而不是繼承來重用組件之間的代碼。
在本節(jié)中,我們將考慮幾個React經(jīng)常需要繼承的開發(fā)人員的問題,并展示如何用組合來解決它們。
有些組件不提前知道他們的孩子。這對于像Sidebar
或Dialog
代表通用“盒子”的組件尤其常見。
我們建議這些組件使用特殊的children
道具將子元素直接傳遞到它們的輸出中:
function FancyBorder(props) { return ( <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} </div> ); }
這可以讓其他組件通過嵌套JSX將任意子對象傳遞給它們:
function WelcomeDialog() { return ( <FancyBorder color="blue"> <h1 className="Dialog-title"> Welcome </h1> <p className="Dialog-message"> Thank you for visiting our spacecraft! </p> </FancyBorder> ); }
<FancyBorder>
JSX標簽內(nèi)的任何東西都會FancyBorder
作為children
道具傳入組件。由于FancyBorder
渲染{props.children}
內(nèi)部<div>
,傳遞的元素出現(xiàn)在最終的輸出中。
雖然這種情況不太常見,但有時您可能需要在組件中出現(xiàn)多個“漏洞”。在這種情況下,你可以拿出你自己的約定,而不是使用children
:
function SplitPane(props) { return ( <div className="SplitPane"> <div className="SplitPane-left">{props.left}</div> <div className="SplitPane-right">{props.right}</div> </div> ); } function App() { return ( <SplitPane left={ <Contacts /> } right={ <Chat /> } /> ); }
反應相似的元素<Contacts />
和<Chat />
只是對象,這樣你就可以通過他們像任何其他數(shù)據(jù)的道具。
有時我們會將組件視為其他組件的“特例”。例如,我們可以說a WelcomeDialog
是一個特例Dialog
。
在React中,這也可以通過組合來實現(xiàn),其中一個更“特定”的組件呈現(xiàn)更“通用”的組件,并使用道具進行配置:
function Dialog(props) { return ( <FancyBorder color="blue"> <h1 className="Dialog-title">{props.title}</h1> <p className="Dialog-message">{props.message}</p> </FancyBorder> ); } function WelcomeDialog() { return ( <Dialog title="Welcome" message="Thank you for visiting our spacecraft!" /> ); }
對于定義為類的組件,組合的作用同樣好:
function Dialog(props) { return ( <FancyBorder color="blue"> <h1 className="Dialog-title">{props.title}</h1> <p className="Dialog-message">{props.message}</p> {props.children} </FancyBorder> ); } class SignUpDialog extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleSignUp = this.handleSignUp.bind(this); this.state = {login: ''}; } render() { return ( <Dialog title="Mars Exploration Program" message="How should we refer to you?"> <input value={this.state.login} onChange={this.handleChange} /> <button onClick={this.handleSignUp}> Sign Me Up!</button> </Dialog> ); } handleChange(e) { this.setState({login: e.target.value}); } handleSignUp() { alert(`Welcome aboard, ${this.state.login}!`); } }
在Facebook上,我們在數(shù)千個組件中使用React,并且我們還沒有發(fā)現(xiàn)任何建議創(chuàng)建組件繼承層次結(jié)構(gòu)的用例。
道具和構(gòu)圖為您提供了所有需要的靈活性,以明確和安全的方式自定義組件的外觀和行為。請記住,組件可以接受任意道具,包括原始值,React元素或函數(shù)。
如果您想在組件之間重用非UI功能,我們建議將其解壓縮到單獨的JavaScript模塊中。組件可以將其導入并使用該函數(shù),對象或類,而不對其進行擴展。