Author avatar

Chris Parker

How to Pass Data between React Components

Chris Parker

  • May 29, 2020
  • 7 Min read
  • 3,637 Views
  • May 29, 2020
  • 7 Min read
  • 3,637 Views
Web Development
Front End Web Development
Client-side Framework
React

Introduction

React is a JavaScript library maintained mainly by Facebook. Despite its popularity, it can be a bit tricky to handle data in React. This guide summarizes three approaches to handling data in React:

  1. Passing data from parent to child using props
  2. Passing data from child to parent employing callbacks
  3. Passing data among siblings. This can be achieved by one of the following methods:

    a. Integrating the methods mentioned above

    b. Using Redux

    c. Utilizing React's Context API.

Read the rest of this guide to better understand these concepts and learn how to implement them.

From Parent to Child Using Props

Try to imagine the directory structure of the app as follows: the parent component actually renders the child components in the app.

1
2
3
4
App
 └── Parent
   ├── Child1
   └── Child2

This is the simplest and most basic direction of data flow in React.

1
2
3
4
5
6
7
8
9
10
11
class Parent extends React.Component {state = { data : "Hello World" } 
render() {
        
        return (
            <div>
                 <Child1/>            //no data to send             
                 <Child2 dataFromParent = {this.state.data} />
            </div>
        );    }
}
//Sending data as a state is not obligatory. You can use simple vars or const variables to pass data from parent to child.
javascript

Use the variable this.props.dataFromParent to obtain the data passed from parent to child.

1
2
3
4
5
6
7
8
9
10
class Child2 extends React.Component {
 render() {
         
         return (
             <div>
                 Data from parent is:{this.props.dataFromParent}
             </div>
         );
     }
 }
javascript

From Child to Parent Using Callbacks

Say you want to send a message from child1 to parent withthe message "Hello, how are you?" Take the following steps:

  1. In the Parent.js, set a callback function to take in the parameter that you have accessed from the child.
  2. Send the callback function to the child1.js as a prop.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Parent extends React.Component {
state = { message: "" }
callbackFunction = (childData) => {
      this.setState({message: childData})
},


 render() {
        return (
            <div>
                 <Child1 parentCallback = {this.callbackFunction}/>
                 <p> {this.state.message} </p>
            </div>
        );
}
}
javascript
  1. Pass your data using this.props.callback(dataToParent) in the child1.js.
1
2
3
4
5
6
7
8
class Child1 extends React.Component{sendData = () => {
         this.props.parentCallback("Hey Popsie, How’s it going?");
    },

render() { 
//Any time you wish to send data from child to parent component, call the sendData function.
    }
};
javascript

Between Siblings

Choosing a method to share data among sibling can be a bit tricky for beginners. This guide covers three popular methods. After you read about them all, you can choose a favorite.

Method 1: Integrate the methods mentioned above .

Despite being a simple method, this does not work for complex directory structures. You might need to do extensive coding to send data between components that are several levels away from each other. Your data then travels back and forth across every intermediate level.

Method 2: Use Redux by maintaining the states of all child components that you might need in a global store and obtain the data from said store.

Method 3: Utilize React's Context API.

Recently, many developers are choosing React's Context API over Redux because the former saves them from prop-drilling. Prop-drilling is a common name for the process of passing down variables to subcomponents. The primary concept is passing the parameters to the following function as you move on.

Take a look the following directory structure that you need to pass data back and forth between Child1 and Child2. In this example, assume that you need to send "How are you?" from Child1 to Child2.

1
2
3
App
├── Child1
└── Child2

This can be done using Context API as follows:

Step 1: Generate a provider component for the two child components.

The major objectives of this provider are:

  1. Maintaining the state, which includes the data that both components will use along with a callback to manipulate it
  2. Returning a contextObject.Provider JSX component

Step 2: Inside the provider component, pass the state and callback mentioned above as props to all child components.

1
2
3
4
5
6
7
8
9
10
11
12
13
export const MContext = React.createContext();  //exporting context object
class MyProvider extends Component {
state = {message: ""}
render() {
        return (
            <MContext.Provider value={
            {   state: this.state,
                setMessage: (value) => this.setState({
                            message: value })}}>
            {this.props.children}   //this indicates that all the child tags with MyProvider as Parent can access the global store.
            </MContext.Provider>)
    }
}
javascript

You can think of the provider as the one in control of its children. This includes the global store of every state as well as the callback functions in charge of handling these states. Thus, any component that needs anything must contact the provider in order to access the objects.

In other words:

  1. In order for Child1 to create or edit the message, it must contact the provider and set its states.
  2. In order for Child2 to view the data, it must access the provider and obtain its states.

Step 3: Set the MyProvider component as a parent to the two child components, Child1 and Child2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class App extends React.Component {
render() {
        return (
            <div>
                 <MyProvider>
                      <div className="App">
                      <Child1/>
                      <Child2/>
                      </div>
               </MyProvider>
            </div>
        );
}
}
javascript

Step 4: Proceed accordingly, using ContextObject.Consumer as illustrated below:.

Since Child1 and Child2 are both set as consumers of the provider, they can access the provider within consumer tags.

1
2
3
4
5
6
7
8
9
10
11
12
13
import MContext
class Child1 extends React.Component {
render() {
    return (
        <div>
        <Mcontext.Consumer>
        {(context) => (
       <button onClick={()=>{context.setMessage("New Arrival")}}>Send</button>
       )}
        </Mcontext.Consumer>
        </div>
    ) }
}
javascript

Now Child2 can receive the data by accessing the provider within the consumer tags.

1
2
3
4
5
6
7
8
9
10
11
12
import MContext
class Child2 extends React.Component {
render() {
       return (
         <div>
            <Mcontext.Consumer>
             {(context) => (
              <p>{context.state.message}}</p>)}
            </Mcontext.Consumer>
         </div>
   )}
}
javascript

Conclusion

This guide covered how to pass data between different components in React in three ways: parent to child, child to parent, and between siblings. It also covered three popular methods for passing data between siblings. You can experiment and use the one that suits your need.

15