我正在尝试找到定义可以以一般方式使用的某些组件的正确方法:
<Parent> <Child value="1"> <Child value="2"> </Parent>
当然,您可以想象<select>并<option>作为该逻辑的示例,在父组件和子组件之间存在一种渲染逻辑。
<select>
<option>
对于这个问题,这是一个虚拟的实现:
var Parent = React.createClass({ doSomething: function(value) { }, render: function() { return (<div>{this.props.children}</div>); } }); var Child = React.createClass({ onClick: function() { this.props.doSomething(this.props.value); // doSomething is undefined }, render: function() { return (<div onClick={this.onClick}></div>); } });
问题是,每当您用于{this.props.children}定义包装器组件时,如何将某些属性传递给其所有子组件?
{this.props.children}
Cloning children with new props
您可以使用React.Children遍历子级,然后使用React.cloneElement使用新的道具(浅合并)克隆每个元素,例如:
const Child = ({ doSomething, value }) => ( <div onClick={() => doSomething(value)}>Click Me</div> ); class Parent extends React.PureComponent { doSomething = value => { console.log('doSomething called by child with value:', value); } render() { const childrenWithProps = React.Children.map(this.props.children, child => React.cloneElement(child, { doSomething: this.doSomething }) ); return <div>{childrenWithProps}</div> } }; ReactDOM.render( <Parent> <Child value="1" /> <Child value="2" /> </Parent>, document.getElementById('container') );
Calling children as a function
您也可以将道具传递给带有渲染道具的孩子。在这种方法中,子代(可以是children或任何其他prop名称)是一个函数,可以接受您要传递的任何参数并返回子代:
children
const Child = ({ doSomething, value }) => ( <div onClick={() => doSomething(value)}>Click Me</div> ); class Parent extends React.PureComponent { doSomething = value => { console.log('doSomething called by child with value:', value); } render() { // Note that children is called as a function and we can pass args to it return <div>{this.props.children(this.doSomething)}</div> } }; ReactDOM.render( <Parent> {doSomething => ( <React.Fragment> <Child doSomething={doSomething} value="1" /> <Child doSomething={doSomething} value="2" /> </React.Fragment> )} </Parent>, document.getElementById('container') );
如果您愿意,也可以代替<React.Fragment>或简单地<>返回一个数组。
<React.Fragment>
<>