An Introduction to Child-Root Data Passing in React.js
Jul 31, 2020 • 6 Minute Read
Introduction
During design and development of front end interfaces in React.js, naturally components have a parent child relationship and data will flow from parent to child. However, some use cases may require that the convention be defied and data be passed upwards from child to parent. In this guide, you will explore this use case in React.js. This guide assumes at least intermediate knowledge and skill level in React.js.
Use Case Scenario
Assume you are the React developer in a micro service architecture based HR project. In your app structure, you have a table in the main file and thus the parent component. The table houses your employee data. You also have a child form component that allows a user, in this case an HR manager, to insert new employees, which should update your table in the parent component. Hence, you need to send your user data back to the parent component.
Environment Setup
You will start by creating a new React app. In your terminal, run the command below. npx create-react-app react-propsOpen your app with your favorite text editor and navigate to the newly created app.js file.
Passing Props from Parent to Child
React has a unidirectional data flow. Think of it as a river flowing from source to destination: the river only flows one way. It's the same when passing data from a parent to child component. You can take a look from the example below. Replace the starter code in app.js with the sample below and change the file name to ParentComponent.js.
import React, {Component} from 'react';import ChildComponent from "./ChildComponent";
class ParentComponent extends Component { constructor(props) { super(props); this.state = ({ value: "", })
this.handleChange = this.handleChange.bind(this); }
handleChange(e) { let name = e.target.value this.setState({ value: name })}
render() { return ( <div>
<input type="text" name="name"
onChange={this.handleChange} /> <ChildComponent fromParent={this.state.value}/> </div> );}}export default ParentComponent;
Here's how your ChildComponent.js should look:
import React, {Component} from "react";
class ChildComponent extends Component{ constructor(props) { super(props); }
render() { return ( <div> <p>{this.props.fromParent}</p> </div> ); }}export default ChildComponent
Pass Props from Child to Parent.
As stated earlier, React has a unidirectional flow of data. To send data back to the parent from the child component you'd need to put in some extra work. Go back to your ChildComponent.js file. In this example, you will pass values from a form in your ChildComponent to your ParentComponent table.
Functions in React provide an easy way to pass data. Every time your input field changes in the ChildComponent, this change will be propagated through your function to the ParentComponent. Your ChildComponent should look like this:
import React, {Component} from "react";
class ChildComponent extends Component{
constructor(props) { super(props) this.state =({ firstName: '', secondName:'',thirdName: ''})
this.handleFirstName = this.handleFirstName.bind(this)
this.handleSecondName = this.handleSecondName.bind(this)
this.handleRole = this.handleRole.bind(this)
this.handleSave = this.handleSave.bind(this); }
handleFirstName(e) { let firstName = e.target.value
this.setState({ firstName: firstName }) } handleSecondName(e) { let secondName = e.target.value this.setState({ secondName: secondName}) }
handleRole(e) { let role = e.target.value this.setState({ role: role }) } handleSave()
{ const { firstName, secondName, role} = this.state
this.props.handleInputChange(firstName, secondName, role) }
render() { return
( <div> <input type="text" name="firstName" onChange=this.handleFirstName}/>
<input type="text" name="secondName" onChange={this.handleSecondName}/>
<input type="text" name="role" onChange={this.handleRole}/>
<button onClick={this.handleSave}>Save</button> </div> )}}export default ChildComponent
Initialize your fields in the constructor, namely firstName, secondName, and role, which will store your state. Next up, you'll write functions to handle changes in input and set state accordingly. Finally, your button, once clicked, will be responsible for sending your form data back to your parent component where you will update your table. This is handled by the this.props.handleInputChange, which takes in the states we initialized as parameters. Your ParentComponent should look like this:
import React, {Component} from 'react';import ChildComponent from "./ChildComponent";
class ParentComponent extends Component { constructor(props) { super(props)
this.state =({ first_name: '', second_name:'', role: '' })
this.handleNewInput = this.handleNewInput.bind(this) } handleNewInput(firstName, secondName,role) { this.setState({ first_name: firstName, second_name: secondName, role: role }) }
render()
{return ( <div> <table> <tbody> <tr>
<th>FirstName</th> <th>LastName</th>
<th>Role</th> </tr> <tr> <td>{this.state.first_name}</td> <td>{this.state.second_name}</td>
<td>{this.state.role}</td> </tr> </tbody></table> <ChildComponent handleInputChange={this.handleNewInput}/> </div> )}}
export default ParentComponent
In the code above, you have created a table that will display our new data. You have also initialized your state to store data passed from your child component. The child component is instantiated within the parent component with a value 'handleInputChange', which holds data passed. Then you can retrieve the data easily by calling this.state in your table.
Conclusion
Being equipped with the skills to pass data from parent to child components and back, you now have the ability to better manipulate data within React components. React and front end developer jobs heavily require this skill. To further build on this guide, you can learn more about React contexts on the official React.js site.