So I was doing a project that in one of its part I needed to get the name of the user and set it on the right side of the top navigation bar. Normally it is easy to pass a value from child component to its parent, simply by setting a parameter in state of the parent and change it in child by changing props like this:
getInitialState: function () { return { isLoading: true, person_name: '' } }, handleUpdateUser: function (event) { this.setState({ person_name: event.target.value }); }, render: function() { return ( <MainContainer> <Start person_name={this.state.person_name} onUpdateUser={this.handleUpdateUser} /> </MainContainer> ); }
and then in the child component we do:
<div className="form-group"> <input className='form-control' onChange={props.onUpdateUser} placeholder='Insert Your Name' type='text' value={props.person_name} /> </div> <div className="form-group col-sm-6 col-sm-offset-3"> <button className="btn btn-block btn-success" type="submit" disabled={!props.person_name}> Start the Test </button> </div>
now in this way we have the input as a state of the parent component but what if we have a situation that I have now. In my main component I have a render part:
<Navbar></Navbar> <div> {this.props.children} </div> <Footer/>
and then I have a navigation component as “Navbar”. I have implemented in the way that on my right navigation part it shows the name which we pass from its parent:
</ul> <ul className="nav navbar-nav navbar-right"> <p className="navbar-brand" style={textname}> {this.props.person_name}</p> </ul>
but the problem is I have a Main component which is the parent of all children and I need to pass a state of one of the child to the other child through the parent so after searching and reading alot, I found this solution which was easy in fact.
I thought that I can set a state of person name in my main and also created a handler for setting that state and passed it to the child component.
getInitialState: function () { return { person_name: '' } }, updateNavbar: function(personName){ this.setState({ person_name: personName }); }
But I didn’t know how I can pass my handler and state to the child component which I don’t know and my router will choose it for me because it is “{this.props.children}”.
Then I found the solution 🙂 Instead of ‘{this.props.children}’ I had to use:
{React.cloneElement(this.props.children, {updateNavbar: this.updateNavbar , person_name : this.state.person_name})}
Now every time I update my input from second level child, it passes from its parent to the Main component and Main will pass it to my Navbar component.