JSX 中的孩子们
在包含开始标记和结束标记的 JSX 表达式中,这些标记之间的内容作为特殊 prop:props.children
传递。通过孩子有几种不同的方法:
字符串文字
你可以在开始和结束标签之间放一个字符串,props.children
就是那个字符串。这对许多内置 HTML 元素很有用。例如:
<MyComponent>
<h1>Hello world!</h1>
</MyComponent>
这是有效的 JSX,MyComponent 中的 props.children
只是 <h1>Hello world!</h1>
。
请注意, HTML 未转义,因此你通常可以像编写 HTML 一样编写 JSX。
请记住,在这种情况下 JSX:
- 删除行开头和结尾的空格;
- 删除空白行;
- 删除与标签相邻的新行;
- 在字符串文字中间出现的新行被压缩到一个空格中。
JSX 儿童
你可以提供更多 JSX 元素作为子项。这对于显示嵌套组件很有用:
<MyContainer>
<MyFirstComponent />
<MySecondComponent />
</MyContainer>
你可以将不同类型的子项混合在一起,因此你可以将字符串文字与 JSX 子项一起使用。这是 JSX 与 HTML 类似的另一种方式,因此这是有效的 JSX 和有效的 HTML:
<div>
<h2>Here is a list</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
请注意,React 组件不能返回多个 React 元素,但单个 JSX 表达式可以有多个子元素。因此,如果你希望组件呈现多个内容,你可以将它们包装在 div
中,如上例所示。
JavaScript 表达式
你可以将任何 JavaScript 表达式作为子项传递,方法是将其包含在 {}
中。例如,这些表达式是等效的:
<MyComponent>foo</MyComponent>
<MyComponent>{'foo'}</MyComponent>
这通常用于呈现任意长度的 JSX 表达式列表。例如,这会呈现一个 HTML 列表:
const Item = ({ message }) => (
<li>{ message }</li>
);
const TodoList = () => {
const todos = ['finish doc', 'submit review', 'wait stackoverflow review'];
return (
<ul>
{ todos.map(message => (<Item key={message} message={message} />)) }
</ul>
);
};
请注意,JavaScript 表达式可以与其他类型的子项混合使用。
作为儿童的功能
通常,在 JSX 中插入的 JavaScript 表达式将计算为字符串,React 元素或这些事物的列表。然而,props.children
就像任何其他道具一样,它可以传递任何类型的数据,而不仅仅是 React 知道如何渲染的类型。例如,如果你有自定义组件,则可以将其作为 props.children
进行回调:
const ListOfTenThings = () => (
<Repeat numTimes={10}>
{(index) => <div key={index}>This is item {index} in the list</div>}
</Repeat>
);
// Calls the children callback numTimes to produce a repeated component
const Repeat = ({ numTimes, children }) => {
let items = [];
for (let i = 0; i < numTimes; i++) {
items.push(children(i));
}
return <div>{items}</div>;
};
传递给自定义组件的子代可以是任何东西,只要该组件将它们转换为 React 在渲染之前可以理解的内容。这种用法并不常见,但如果你想扩展 JSX 的功能,它就有用了。
忽略的值
请注意,false
,null
,undefined
和 true
是有效的孩子。但他们根本就没有渲染。这些 JSX 表达式将呈现相同的东西:
<MyComponent />
<MyComponent></MyComponent>
<MyComponent>{false}</MyComponent>
<MyComponent>{null}</MyComponent>
<MyComponent>{true}</MyComponent>
这对于有条件地呈现 React 元素非常有用。这个 JSX 只渲染 if showHeader
为真:
<div>
{showHeader && <Header />}
<Content />
</div>
一个重要的警告是,一些假的值,例如 0
号,仍然由 React 呈现。例如,此代码的行为不会像你预期的那样,因为当 props.messages
为空数组时将打印 0
:
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
解决此问题的一种方法是确保 &&
之前的表达式始终为 boolean:
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
最后,请记住,如果你希望输出中出现 false
,true
,null
或 undefined
等值,则必须先将其转换为字符串:
<div>
My JavaScript variable is {String(myVariable)}.
</div>