简体   繁体   中英

How to pass props props from Parent to this.props.children in React

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 .

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"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM