React.Children
React.Children 为处理 this.props.children 的未知数据结构提供了解决方法。
- 任何东西都能是一个
child
1 | <Grid> |
React中的 Children 不一定是组件,它们可以使任何东西。例如,我们能够直接将文字作为 children 传递我们的 <Grid /> 组件。
JSX将会自动删除每行开头和结尾的空格,以及空行。它还会把字符串中间的空白行压缩为一个空格。
1 | <Grid>Hello world!</Grid> |
我们能够传递任何的 JavaScript表达式 作为children,包括函数。
1 | class Executioner extends React.Component { |
我们可以像下面这样使用上面的组件
1 | <Executioner> |
React.Children.map
1 | React.Children.map(this.props.children, function (child) { |
需要注意, this.props.children 的值有三种可能:如果当前组件没有子节点,它就是 undefined;如果有一个子节点,数据类型是 object;如果有多个子节点,数据类型就是 array。所以,处理 this.props.children 的时候要小心。
React 提供一个工具方法 React.Children 来处理 this.props.children。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是object。
1 | <NotesList> |
React.Children.forEach
React.Children.forEach(children, function [(this.Arg)])
类似于 React.Children.map(),但是不返回对象。
React.Children.count
number React.Children.count(children)
返回 children 当中的组件总数,和传递给 map 或者 forEach 的回调函数的调用次数一致。
React.Children.only
object React.Children.only(children)
1 | // 上面的 <Executioner /> 组件,它只能在传递单一child的情况下使用,而且child必须为函数。可以像下面这么写 |
返回 children 中 仅有的子级。否则抛出异常。
这里仅有的子级,only 方法接受的参数只能是一个对象,不能是多个对象(数组)。
实际应用(编辑 children )
我们可以将任意的组件呈现为 children ,但是仍然可以用父组件去控制它们,而不是用渲染的组件。为了说明这点,让我们举例一个能够拥有很多 RadioButton 组件的 RadiaGroup 组件。
RadioButton 不会从 RadioGroup 本身上进行渲染,它们只是作为 children 使用。这意味着我们将会有这样的代码。
1 | render() { |
为了把 input 标签弄到同组,必须拥有相同的 name 属性。当然我们可以直接给每个RadioButton 的 name 赋值,但是这个是无聊的并且容易出错。
1 | <RadioGroup> |
改变 children 属性
在RadioGroup 中我们将会添加一个叫做 renderChildren 的方法,在这里我们编辑children的属性
1 | class RadioGroup extends React.Component { |
那么如何编辑它们的属性呢?
永恒地克隆元素
React.cloneElement 会克隆一个元素。我们将想要克隆的元素当作第一个参数,然后将想要设置的属性以对象的方式作为第二个参数。
1 | renderChildren() { |
最后一步就是传递一个唯一的 name 给RadioGroup
1 | <RadioGroup name="g1"> |