在我们编写组件的时候,常常会遇到组件内部使用组件的情况;我们直接将内容写在组件内部,内容是无法渲染的那么我们应该如何在组件内部使用组件呢?
包含关系
有些组件无法提前知晓它们子组件的具体内容。在 Sidebar
(侧边栏)和 Dialog
(对话框)等展现通用容器(box)的组件中特别容易遇到这种情况。
我们建议这些组件使用一个特殊的 children
prop 来将他们的子组件传递到渲染结果中:
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>
);
}
在 CodePen 上尝试
<FancyBorder>
JSX 标签中的所有内容都会作为一个 children
prop 传递给 FancyBorder
组件。因为 FancyBorder
将 {props.children}
渲染在一个 <div>
中,被传递的这些子组件最终都会出现在输出结果中。
少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用 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 (
<SplitPan left={
<Contacts /> } right={
<Chat /> } />
);
}
<Contacts />
和 <Chat />
之类的 React 元素本质就是对象(object),所以你可以把它们当作 props,像其他数据一样传递。这种方法可能使你想起别的库中“槽”(slot)的概念,但在 React 中没有“槽”这一概念的限制,你可以将任何东西作为 props 进行传递。