Reputation: 1787
I have difficulties trying to pass props to this.props.children
. I know there's a few similar posts, however, I believe I have tried most of the accepted solutions, and it's still not behaving and expected. So, I guess I'm missing something vital.
The general idea is this: I have a <NavBar>
component that I would like to wrap around my pages as shown below. I'd like for the wrapped page to accept props passed down from the <NavBar>
component.
<NavBar>
<Container>
<Grid container>
<Grid item>
...
</Grid>
</Grid>
</Container>
</NavBar>
Currently my <NavBar>
is defined as such:
class NavBar extends React.Component<React.PropsWithChildren<NavBarProps>, NavBarState>
So, my component has a prop children?: React.ReactNode
. In my render()
method I am rendering an <AppBar>
(from Material UI library) underneath which I display the children
similar as such:
render() {
const {children} = this.props;
return(
<>
<AppBar>...</AppBar>
{children}
</>
)
}
Some attempts I've had:
render() {
const children = React.cloneElement(this.props.children as React.ReactElement, {
test: "test"
});
return(
<>
<AppBar>...</AppBar>
{children}
</>
)
}
What I expect: In this case, I would like to be able to access the test
props from any page wrapped within <NavBar>
like this.props.test
I also tried:
const children = React.Children.map(this.props.children as React.ReactElement, (child) =>
React.cloneElement(child, { test: "test" })
);
&
const children = React.Children.map<ReactNode, ReactNode>(this.props.children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { test: "test" });
}
});
Result so far: I've been unsuccessful and trying to access this.props.test
from my page returns undefined
.
Upvotes: 2
Views: 792
Reputation: 14395
I don't see anything wrong with your third attempt. Here is a working example using that method. Notice unlike your second attempt, you do need to return
from the map
.
function Test() {
return (
<Parent>
<Child />
</Parent>
);
}
class Parent extends React.Component {
render() {
const children = React.Children.map(this.props.children, (child) => {
return React.cloneElement(child, {test: 'test'});
});
return (
<div>
<h3>Parent</h3>
{children}
</div>
);
}
}
class Child extends React.Component {
render() {
return (
<div>
<h3>Child</h3>
Test Prop: {this.props.test}
</div>
);
}
}
ReactDOM.render(<Test/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
Upvotes: 1