我试图找到定义可以以一般方式使用的组件的正确方法:
<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}
用新道具克隆Children
您可以使用React.Children遍历子级,然后使用React.cloneElement使用新的道具(浅合并)克隆每个元素,例如:
import React, { Children, isValidElement, cloneElement } from 'react'; const Child = ({ doSomething, value }) => ( <div onClick={() => doSomething(value)}>Click Me</div> ); function Parent({ children }) { function doSomething(value) { console.log('doSomething called by child with value:', value); } render() { const childrenWithProps = Children.map(children, child => { // Checking isValidElement is the safe way and avoids a TS error too. if (isValidElement(child)) { return cloneElement(child, { doSomething }) } return child; }); return <div>{childrenWithProps}</div> } }; ReactDOM.render( <Parent> <Child value="1" /> <Child value="2" /> </Parent>, document.getElementById('container') );
小提琴:https : //jsfiddle.net/2q294y43/2/
称呼children为功能
您也可以将道具传递给带有渲染道具的children。在这种方法中,子代(可以是children或任何其他prop名称)是一个函数,可以接受您要传递的任何参数并返回子代:
children
const Child = ({ doSomething, value }) => ( <div onClick={() => doSomething(value)}>Click Me</div> ); function Parent({ children }) { function 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>{children(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>
<>
小提琴:https : //jsfiddle.net/ferahl/y5pcua68/7/