我正在尝试找到正确的方法来定义一些可以以通用方式使用的组件:
<Parent>
<Child value="1">
<Child value="2">
</Parent>
当然,父子组件之间的渲染是有逻辑的,你可以想象<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}
要定义一个包装器组件,如何将一些属性传递给它的所有子组件?
最佳答案
用新 Prop 克隆 child
您可以使用 React.Children
遍历子元素,然后使用 React.cloneElement
使用新的 Prop (浅合并)克隆每个元素.
查看代码注释为什么我不推荐这种方法。
const Child = ({ childName, sayHello }) => (
<button onClick={() => sayHello(childName)}>{childName}</button>
);
function Parent({ children }) {
// We pass this `sayHello` function into the child elements.
function sayHello(childName) {
console.log(`Hello from ${childName} the child`);
}
const childrenWithProps = React.Children.map(children, child => {
// Checking isValidElement is the safe way and avoids a
// typescript error too.
if (React.isValidElement(child)) {
return React.cloneElement(child, { sayHello });
}
return child;
});
return <div>{childrenWithProps}</div>
}
function App() {
// This approach is less type-safe and Typescript friendly since it
// looks like you're trying to render `Child` without `sayHello`.
// It's also confusing to readers of this code.
return (
<Parent>
<Child childName="Billy" />
<Child childName="Bob" />
</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>
将 child 作为函数调用
或者,您可以通过 render props 将 Prop 传递给 child 。 .在这种方法中, child (可以是 children
或任何其他 Prop 名称)是一个可以接受您想要传递的任何参数并返回实际 child 的函数:
const Child = ({ childName, sayHello }) => (
<button onClick={() => sayHello(childName)}>{childName}</button>
);
function Parent({ children }) {
function sayHello(childName) {
console.log(`Hello from ${childName} the child`);
}
// `children` of this component must be a function
// which returns the actual children. We can pass
// it args to then pass into them as props (in this
// case we pass `sayHello`).
return <div>{children(sayHello)}</div>
}
function App() {
// sayHello is the arg we passed in Parent, which
// we now pass through to Child.
return (
<Parent>
{(sayHello) => (
<React.Fragment>
<Child childName="Billy" sayHello={sayHello} />
<Child childName="Bob" sayHello={sayHello} />
</React.Fragment>
)}
</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>
关于javascript - 如何将 Prop 传递给 {this.props.children},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32370994/