Tuesday, May 8, 2018

Passing a value onto a child component (this.props.children) in react

Leave a Comment

I have a child component in a Layout that I want to pass a props value too. But I don't know how. In the class below the layoutFileDataRequest() receives a string variable from a child component on a click event. There is a need to send that value to one of the this.props.children components so it can update.

How do I do this? In the code below React.cloneElement(child, { does not change it always stays the same which means I can't update the child prop.

  export default class Layout extends React.Component {     constructor(props) {       super(props)        this.layoutFileDataRequest = this.layoutFileDataRequest.bind(this);       this.state = {         newData: '',         returnData: 'test',        }     }      /**      *  Received request from server add it to       *  react component so that it can be rendered      */     layoutFileDataRequest(data) {       this.setState({ returnData:data })     }       renderChildren() {       return React.Children.map(this.props.children, child => {         console.log(this.state.returnData);            return React.cloneElement(child, {             data: this.state.returnData           })       });     }       /**      *  Render request      *       *       */     render() {       const { location } = this.props;       const title = this.state.newData;       return (         <div id="app-container" class={title}>           <Nav location={location} />           <main id="main">             <h1>{title}</h1>             <section>                 {this.renderChildren()}             </section>           </main>           <Project layoutFileDataRequest={this.layoutFileDataRequest} />           <Footer />         </div>       );     }   }   export default class Project extends React.Component {   constructor(props) {     super(props)      this.projectFileDataRequest = this.projectFileDataRequest.bind(this);      this.state = {       newData: [],     }    }     /**    *  Received request from server add it to     *  react component so that it can be rendered    */   projectFileDataRequest(data) {     this.props.layoutFileDataRequest(data);   }     /**    *  Received request from server add it to     *  react component so that it can be rendered    */   componentDidMount() {     ApiCalls.readSassDirData()       .then(function (serverData) {         this.setState({ newData: serverData[0].data })       }.bind(this));   }     /**    *  Render request    */   render() {     const listOfObjects = this.state.newData;     return (       <aside id="project">         <h2>Files</h2>         <FileListing listOfObjects={listOfObjects} projectFileDataRequest={this.projectFileDataRequest} />,        </aside>     );   } } 

2 Answers

Answers 1

I think the error is in the renderChildren function.

Code

 renderChildren() {       return React.Children.map(this.props.children, child => {         console.log(this.state.returnData);            return React.cloneElement(child, {             data: this.state.returnData           })       });     } 

New Code

renderChildren(){     return this.props.children.map(child =>          React.cloneElement(child, {              data: {...this.state.returnData }         })     ); } 

Answers 2

There's nothing wrong with the actual code, the only thing that i am guessing is happening is that in the <FileListing /> component there is not and invocation to the prop (method) projectFileDataRequest passing the update that wants to be transfer it to the <Layout />'s children.

TL;DR... Here is your code working and updating the <Layout />'s children just after receiving a click event in <FileListing />.

https://codesandbox.io/s/5050w0p9kx

I hope it helps you

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment