包含关系
有些组件无法提前知晓它们子组件的具体内容. 在Sidebar和Dialog等展现通用容器的组件中特别容易遇到这种情况.
我们建议这些组件使用一个特殊的children prop来将他们的子组件传递到渲染结果中:
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
少数情况下, 可能需要在一个组件中预留几个"洞". 这种情况下, 我们可以不使用children, 而是自行约定: 将所需内容传入props, 并使用相应的prop.
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 />
} />
);
}
特殊关系
有些时候, 我们会把一些组件看作是其他组件的特殊实例, 比如WelcomeDialog可以说是Dialog的特殊实例.
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!" />
);
}
我们推荐使用组合而非继承来实现组件间的代码重用.