我试图将额外的道具传递给this.props.children,我看到了这个答案how to pass props to children with React.cloneElement?
从某种原因,虽然我没有收到任何错误,但我看不到道具
所以我有这个状态
this.state = {
open: true
}
我希望将其传递给this.props.children,这是我迄今为止所做的:
{
React.Children.map(this.props.children, child =>
React.cloneElement(child, {sidebarState: this.state.open}))
}
当我在console.logging this.props对孩子们时,我看不到我的新道具。
---编辑--- 孩子们看起来像这样:
render() {
console.log(this.props)
// other code
}
BTW我正在使用react 16.0
答案 0 :(得分:2)
将道具传递给儿童有两种方式:
儿童作为职能
孩子不是一个React元素,而是一个函数。
调用子功能:
const List = ({ children, sidebarState }) => (
<ul>
{
children(sidebarState)
}
</ul>
);
传递孩子的功能:
<List sidebarState={sidebarState}>
{
(sidebarState) => (
<Item sidebarState={sidebarState} />
)
}
</List>
工作示例:
const { Component } = React;
const Item = ({ sidebarState }) => (
<li>{sidebarState ? 'open' : 'close'}</li>
);
const List = ({ children, sidebarState }) => (
<ul>
{
children(sidebarState)
}
</ul>
);
class App extends Component {
constructor(props) {
super(props);
this.state = {
sidebarState: true
}
}
toggleOpen = () => this.setState((prevState) => ({
sidebarState: !prevState.sidebarState
}));
render() {
const { sidebarState } = this.state;
return (
<div>
<button onClick={this.toggleOpen}>Toggle</button>
<List sidebarState={sidebarState}>
{
(sidebarState) => (
<Item sidebarState={sidebarState} />
)
}
</List>
</div>
);
}
}
ReactDOM.render(
<App />,
demo
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>
<强> React.cloneElement 强>
工作示例:
const { Component } = React;
const Item1 = ({ sidebarState }) => (
<li>{sidebarState ? 'open' : 'close'}</li>
);
const Item2 = ({ sidebarState }) => (
<li>{sidebarState ? 'open' : 'close'}</li>
);
const List = ({ children, sidebarState }) => (
<ul>
{
React.Children.map(children, (child) => React.cloneElement(child, { sidebarState }))
}
</ul>
);
class App extends Component {
constructor(props) {
super(props);
this.state = {
sidebarState: true
}
}
toggleOpen = () => this.setState((prevState) => ({
sidebarState: !prevState.sidebarState
}));
render() {
const { sidebarState } = this.state;
return (
<div>
<button onClick={this.toggleOpen}>Toggle</button>
<List sidebarState={sidebarState}>
<Item1 />
<Item2 />
</List>
</div>
);
}
}
ReactDOM.render(
<App />,
demo
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>
答案 1 :(得分:0)
这里是一个例子。
之前(不将道具传递到children
)
<div className="layout">
{children}
</div>
之后(向每个孩子传递额外的props1
和props2
道具):
<div className="layout">
{
React.Children.map(children, (child) => {
return React.cloneElement(child, {
props1: 1,
props2: 2,
});
})
}
</div>
props1
和props2
与每个孩子的现有道具合并。
关于TypeScript类型,您必须使用React.ReactElement
而不是React.ReactNode
,否则TS编译器会在React.Children.map
处抱怨(或ts忽略它):
type Props = {
children: React.ReactElement;
};
有关更多说明,请参见https://medium.com/better-programming/passing-data-to-props-children-in-react-5399baea0356,这对我的理解非常有帮助! (#mediumPaywall)