Communication between Components and Two way binding in React

May 17, 2020
by Moiz Shaikh
  • Featured image React data binding

React Components are essential building block of any react application. These components can communicate and can share different relationships with each other. Communication between these components essentially links the hierarchy of a react application. In this article, we will be looking at parent-child communication and vice versa. We will also look at two way binding in React.

Let us move forward with a code example. We will create a class component called Blogs which will hold a list of recent posts. We will then pass this data to the child component called Post.

Parent To Child communication in React

This is the most straightforward way of communication between 2 react components. It is the one, which you will end up using in every react application you build. Here, the parent component passes data to the child component when invoking the child component. We then reference this data using props(name could be anything) in the child component. You should use these props as is, and never manipulate(mutate) them.

Blogs.js
import React, { Component } from 'react';
import Post from  './Post';
import Feedback from './Feedback';
import './Blogs.css';

class Blogs extends Component{

 state = {
   posts: [
     {
       article: "Two way binding in React",
       author: "Moiz"
     },
     {
       article: "Class based and function based components in react",
       author: "Moiz"
     },
     {
       article: "Angular Toaster Notification Tutorial",
       author: "Rahil"
     }
   ],
   feedback: "Enter your feedback"
 }
   
 render() {
   const post = this.state.posts.map((el, index) => {
     return <Post article = {el.article} author = {el.author} key = {index}/>
    })

   return <div className = "container">
            <p>Recent Posts on Ciphertrick</p>
            <div>
              {post}
            </div>
          </div>
  }
}

export default Blogs;

In the above code, we loop through the data stored inside of state and pass on the data as article and author to the child component i.e Post Component.

Post.js
import React from 'react';
import './Post.css';

const Post = (props) => {
   
  return <div className = "postBlock">
           <div className = "content">Article: {props.article}</div>
           <div className = "content">Author: <b>{props.author}</b></div>
         </div>
}

export default Post
Data sent from the Parent component is received as parameters. We then refer the same using props and display the article and its author.

Child To Parent Communication in React

Now what if the child wants to communicate back to its parent? The child component can essentially let its parent know about events. In the above Post component, let us add delete a button next to each post. When a user clicks delete, It must remove that article from the list. We will add an onClick event on the child component, and pass a reference from the parent component.

Blogs.js
import React, { Component } from 'react';
import Post from  './Post';
import Feedback from './Feedback';
import './Blogs.css';

class Blogs extends Component{

 state = {
   posts: [
     {
       article: "Two way binding in React",
       author: "Moiz"
     },
     {
       article: "Class based and function based components in react",
       author: "Moiz"
     },
     {
       article: "Angular Toaster Notification Tutorial",
       author: "Rahil"
     }
   ],
   feedback: "Enter your feedback"
 }

 onDeletePost = (ind) => {
      let currentPost = []
      currentPost = this.state.posts.filter((el, index ) => {
        return ind !== index
      })
      this.setState({
        posts: currentPost
      })
   }
   
 render() {
   const post = this.state.posts.map((el, index) => {
     return <Post article = {el.article} author = {el.author} key = {index}
             delete = {() => this.onDeletePost(index)}
            />
    })

   return <div className = "container">
            <p>Recent Posts on Ciphertrick</p>
            <div>
              {post}
            </div>
          </div>
  }
}

export default Blogs;

Here, we’ve created an onDeletePost() method and have passed its reference as ‘delete’ to the child component. The onDeletePost() uses the index of the array element to delete the appropriate article.

Post.js
import React from 'react';
import './Post.css';

const Post = (props) => {
  return <div className = "postBlock">
            <div className = "content">Article: {props.article}</div>
            <div className = "content">Author: <b>{props.author}</b></div>
            <button onClick = {props.delete}>Delete</button>
         </div>
}

export default Post

Inside the child component, we have attached an onClick event to the button element. Whenever the button is clicked, the event will be received by the parent component which will then execute the onDeletePost() method.

Two Way Binding in React

Till now, we saw how to communicate between parent and child components one at a time. What if we want bi-directional communication simultaneously between the parent and child components?
Well, we will add an input element inside of the new Feedback component, where you can write some text as feedback.

Feedback.js
import React from 'react';
import './Feedback.css';

const Feedback = (props) => {
 return  <div className = "inputcontainer">
           <label>Feedback:
             <input
               type = "text" name = "feedback"
               value = {props.value}
               onChange = {props.change}/>
           </label>
         </div>
}

export default Feedback;

The feedback component consists of an input element where users can type their feedback. An onChange event is attached to the input element, which gets triggered every time the user types some text in it. Inside the class component we use the onFeedbackChange() method to update the contents of the state and pass the data again to the feedback component as props, thus binding both the components.

Blogs.js
import React, { Component } from 'react';
import Post from  './Post';
import Feedback from './Feedback';
import './Blogs.css';


class Blogs extends Component{

  state = {
   posts: [
     {
       article: "Two way binding in React",
       author: "Moiz"
     },
     {
       article: "Class based and function based components in react",
       author: "Moiz"
     },
     {
        article: "Angular Toaster Notification Tutorial",
        author: "Rahil"
     }
   ],
   feedback: "Enter your feedback"
  }
   
 onDeletePost = (ind) => {
    let currentPost = []
    currentPost = this.state.posts.filter((el, index )=> {
      return ind !== index
    })

    this.setState({
      posts: currentPost
    })

 }

 onFeedbackChange = (e) => {
  this.setState({feedback: e.target.value})
 }


  render() {
    const post = this.state.posts.map((el, index) => {
      return <Post article = {el.article} author = {el.author} key = {index}
               delete = {() => this.onDeletePost(index)}
               />
    })

    return <div className = "container">
             <p>Recent Posts on Ciphertrick</p>
             <div>
                {post}
             </div>
             <Feedback value = {this.state.feedback} change = {this.onFeedbackChange}/>
           </div>
  }
}

export default Blogs;

Inside the class component, we are now invoking the Feedback component as well, and passing the state's feedback value to it.

As mentioned earlier the onFeedbackChange() gets executed every time the value in Feedback component’s input element change. The onFeedbackChange() method receives an event and we use its target.value property to get the existing value of the input element. We then set the state’s feedback property to target.value.

In this way, we essentially achieve a two way binding between these two components.

So To Conclude.

The above-mentioned techniques are some of the basic and important ways of communication between a parent and a child component. With that being said, these are not the only ways components can communicate. There are other ways of sharing data like using React’s context API and other third-party libraries like Redux. I’ll be covering these topics in detail in a separate article. If you have any queries, feel free to drop a comment below. The GitHub repo for the above example code https://github.com/Moiz47/react-data-binding.git

The CSS files for the code above.

blogs.css
.container{
  width: 40%;
  margin: 5px auto;  
  box-sizing: border-box;
  box-shadow: 2px 2px 4px #aaaaaa;
}

p{
  margin: 0px;
  text-align: center;
  padding: 10px 0px;
  font-size: 18px;
}
post.css
.postBlock{
    width: 80%;
    height: 90px;
    border: 1px solid black;
    margin: 20px auto;
    margin-bottom: 20px;
    font-size: 15px;
    box-sizing: border-box;
}

button{
    background-color: white;
    border: 1px solid red;
    border-radius: 2px;
    color: red;
    padding: 3px 6px;
    margin: 5px 10px;
    text-align: center;
    font-size: 12px;
    float: right;
  }

.content{
    padding: 3px 5px;
}
feedback.css
input{
  margin: 10px 10px;
  width: 70%
}

.inputcontainer{
  width: 80%;
  margin: 10px auto;
  text-align: center;
}

Further Reading…

About

Jr. Software developer, Skilled in frontend technologies like React and Angular | Backend technologies like node and Express | SQL and NoSql Database.

Get notified on our new articles

Subscribe to get the latest on Node.js, Angular, Blockchain and more. We never spam!
First Name:
Email:

Leave a Comment