?
本文檔使用 PHP中文網(wǎng)手冊(cè) 發(fā)布
React具有強(qiáng)大的組合模型,我們推薦使用組合而不是繼承來(lái)重用組件之間的代碼。
在本節(jié)中,我們將考慮幾個(gè)React經(jīng)常需要繼承的開(kāi)發(fā)人員的問(wèn)題,并展示如何用組合來(lái)解決它們。
有些組件不提前知道他們的孩子。這對(duì)于像Sidebar
或Dialog
代表通用“盒子”的組件尤其常見(jiàn)。
我們建議這些組件使用特殊的children
道具將子元素直接傳遞到它們的輸出中:
function FancyBorder(props) { return ( <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} </div> ); }
這可以讓其他組件通過(guò)嵌套JSX將任意子對(duì)象傳遞給它們:
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標(biāo)簽內(nèi)的任何東西都會(huì)FancyBorder
作為children
道具傳入組件。由于FancyBorder
渲染{props.children}
內(nèi)部<div>
,傳遞的元素出現(xiàn)在最終的輸出中。
雖然這種情況不太常見(jiàn),但有時(shí)您可能需要在組件中出現(xiàn)多個(gè)“漏洞”。在這種情況下,你可以拿出你自己的約定,而不是使用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 /> } /> ); }
反應(yīng)相似的元素<Contacts />
和<Chat />
只是對(duì)象,這樣你就可以通過(guò)他們像任何其他數(shù)據(jù)的道具。
有時(shí)我們會(huì)將組件視為其他組件的“特例”。例如,我們可以說(shuō)a WelcomeDialog
是一個(gè)特例Dialog
。
在React中,這也可以通過(guò)組合來(lái)實(shí)現(xiàn),其中一個(gè)更“特定”的組件呈現(xiàn)更“通用”的組件,并使用道具進(jì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!" /> ); }
對(duì)于定義為類(lèi)的組件,組合的作用同樣好:
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上,我們?cè)跀?shù)千個(gè)組件中使用React,并且我們還沒(méi)有發(fā)現(xiàn)任何建議創(chuàng)建組件繼承層次結(jié)構(gòu)的用例。
道具和構(gòu)圖為您提供了所有需要的靈活性,以明確和安全的方式自定義組件的外觀和行為。請(qǐng)記住,組件可以接受任意道具,包括原始值,React元素或函數(shù)。
如果您想在組件之間重用非UI功能,我們建議將其解壓縮到單獨(dú)的JavaScript模塊中。組件可以將其導(dǎo)入并使用該函數(shù),對(duì)象或類(lèi),而不對(duì)其進(jìn)行擴(kuò)展。