如何将道具传递给 {this.props.children} [英] How to pass props to {this.props.children}
问题描述
我正在尝试找到定义一些可以以通用方式使用的组件的正确方法:
I'm trying to find the proper way to define some components which could be used in a generic way:
<Parent>
<Child value="1">
<Child value="2">
</Parent>
当然,父子组件之间的渲染是有逻辑的,你可以把 和
想象成这样的例子逻辑.
There is a logic going on for rendering between parent and children components of course, you can imagine <select>
and <option>
as an example of this logic.
这是一个用于问题目的的虚拟实现:
This is a dummy implementation for the purpose of the question:
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}
来定义一个包装组件时,你如何将一些属性传递给它的所有子组件?
The question is whenever you use {this.props.children}
to define a wrapper component, how do you pass down some property to all its children?
推荐答案
用新道具克隆孩子
您可以使用 React.Children
来迭代子元素,然后使用 使用新道具(浅合并)克隆每个元素React.cloneElement
.例如:
const Child = ({ doSomething, value }) => (
<button onClick={() => doSomething(value)}>Click Me</button>
);
function Parent({ children }) {
function doSomething(value) {
console.log("doSomething called by child with value:", value);
}
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, { 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>
或者,您可以使用渲染道具将道具传递给孩子.在这种方法中,子项(可以是 children
或任何其他道具名称)是一个可以接受您想要传递的任何参数并返回子项的函数:
Alternatively, you can pass props to children with render props. In this approach, the children (which can be children
or any other prop name) is a function which can accept any arguments you want to pass and returns the children:
const Child = ({ doSomething, value }) => (
<button onClick={() => doSomething(value)}>Click Me</button>
);
function Parent({ children }) {
function doSomething(value) {
console.log("doSomething called by child with value:", value);
}
// Note that children is called as a function and we can pass args to it.
return <div>{children(doSomething)}</div>
}
function App() {
// doSomething is the arg we passed in Parent, which
// we now pass through to Child.
return (
<Parent>
{doSomething => (
<React.Fragment>
<Child doSomething={doSomething} value={1} />
<Child doSomething={doSomething} value={2} />
</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>
如果你愿意,你也可以返回一个数组,而不是
或简单的 <>
.
Instead of <React.Fragment>
or simply <>
you can also return an array if you prefer.
这篇关于如何将道具传递给 {this.props.children}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!