我试图找到一种合适的方法来定义一些可以通用使用的组件:
<Parent>
<Child value="1">
<Child value="2">
</Parent>
在父组件和子组件之间呈现有一个逻辑当然,您可以想象和
作为这种逻辑的示例。
就问题而言,这是一个虚拟实现:
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}
定义包装器组件时,如何将某些属性传递给它的所有子组件?
您可以使用react.childress
迭代子元素,然后使用react.cloneElement
用新道具克隆每个元素(浅层合并)。例如:
null
const Child = ({ doSomething, value }) => (
<button onClick={() => doSomething(value)}>Click Me</button>
);
class Parent extends React.Component{
doSomething = value => {
console.log("doSomething called by child with value:", value);
}
render() {
const childrenWithProps = React.Children.map(this.props.children, child => {
// checking isValidElement is the safe way and avoids a typescript error too
if (React.isValidElement(child)) {
return React.cloneElement(child, { doSomething: this.doSomething });
}
return child;
});
return <div>{childrenWithProps}</div>;
}
}
function App() {
return (
<Parent>
<Child value={1} />
<Child value={2} />
</Parent>
);
}
ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="container"></div>
想要一种稍微干净的方法,请尝试:
<div>
{React.cloneElement(this.props.children, { loggedIn: this.state.loggedIn })}
</div>
编辑:要与多个单独的子项一起使用(子项本身必须是一个组件),您可以这样做。在16.8.6中测试过
<div>
{React.cloneElement(props.children[0], { loggedIn: true, testingTwo: true })}
{React.cloneElement(props.children[1], { loggedIn: true, testProp: false })}
</div>
试试这个
<div>{React.cloneElement(this.props.children, {...this.props})}</div>
使用React-15.1对我来说很管用。