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.

Leave a comment