How data is handled between Components in React (State vs Props)

Table of contents
Reading Time: 3 minutes

Prerequisites :

Basic understanding of React. Here’s a blog you can refer to :
Getting Started with React

PROPS

Every component in react have a property called props associated to it. This lets you make a single component that is used in many different places in your app, with slightly different properties in each place.

If we write a react component in es5, it’s nothing but a function that takes props as parameters and returns JSX element.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


ES5 :
function MyComponent(props) {
return <h1>Hello World}</h1>;
}
ES6
class MyComponent extends Component {
render() {
return <h1>Hello World}</h1>;
}
}
view raw

react2

hosted with ❤ by GitHub

A parent component can send some data to its child components via props.

But HOW?

We’ll find that out in a minute, but first there are two rules that we need to cover.

    1. RULE 1 : Props are read only
      That means, you cannot re-assign to the props.

 

  1. RULE 2 : Every component must be a pure function with respect to its props.
    A pure function is a function whose output is always same for the same arguments. For eg :
    sum(a, b) {
    return a + b;
    }

Let’s create a basic react app. Follow these steps:

npm install -g create-react-app
create-react-app my-app

cd my-app
npm start

To send data to a child component, we can add multiple properties to that component while rendering it.

For eg,

Consider a child component say Child.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


import React, { Component } from 'react';
class Child extends Component {
render() {
return (
<h1>Say my name</h1>
);
}
}
export default Child;
view raw

Child.js

hosted with ❤ by GitHub

Here’s a very simple component that renders the h1 tag.

Now, when we render this component, we can add certain properties to it like,

 

When the Child component get’s initialised, it will have a name property with value “Heisenberg” in it’s props object.

To display that property in child component, you can use the curly braces,



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


class Child extends Component {
render() {
return (
<h1>{this.props.name}</h1>
);
}
}
view raw

Child2.js

hosted with ❤ by GitHub

STATE

We use state when we need to update the displayed data within the component. If we display some data in JSX. Even if we update the data, it won’t reflect on your DOM.

But if we display data via state, we can update that on DOM as well.

Every component has a state object associated to it, that we initialise in it’s constructor. Before doing that, to be able to access “this” in constructor, since we extend Reacts’ Component class to our ES6 class, we need to call super in the constructor.

constructor() {
super();
this.state= {name: ‘Heisenberg’}
}

and then, in the JSX, we will display it like :

{this.state.name}

 

And to update the state, we will use setState method.

Let’s add a setInterval method to see the effect of state,



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


import React, { Component } from 'react';
class MyComponent extends Component {
constructor() {
super();
this.state= {name: 'Say my name'};
setInterval(
() => {
this.setState({name: 'Heisenberg'})
},
2000
);
}
render() {
return (
<h1>{this.state.name}</h1>
);
}
}
export default MyComponent;
view raw

gistfile1.js

hosted with ❤ by GitHub

A very simple method in constructor, that updates the state after 2 seconds. And hence, the DOM also gets updated after 2 seconds. It should look something like this.

Note: If you look in the DOM, you’ll se that only that particular h1 tag gets updated, and the remaining DOM does not update. React maintains a virtual DOM fot itself and keeps on updating that virtualr DOM. Only if there’s a difference in original DOM and virtual DOM, the changed part of the original DOM get’s updated.

Using states and props together:

Most of the time, a state of one component becomes the props of the child component.

For eg:

For Child component, name property is immutable, and if we need to change it, we’ll have to call the parent’s setState, and the React will update that on the child component.

But if the Child want’s to update the state, it can be done through parent callback and child event.

Child will pass the new name to the callback by calling :
this.props.onNameChange

Let’s have a look at our final components :

App.js :



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


class App extends Component {
constructor() {
super()
this.state = {name: 'Say my name'}
}
handleName(newName) {
this.setState({ name: newName});
}
render() {
return (
<div className="App">
<Child name={this.state.name} onNameChange={this.handleName.bind(this)}/>
</div>
);
}
}
export default App;
view raw

App.js

hosted with ❤ by GitHub

Child.js :



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


class Child extends Component {
constructor() {
super();
}
handleChangeEvent() {
this.props.onNameChange('Heisenberg')
}
render() {
return (
<div>
<h1>{this.props.name}</h1>
<button onClick={this.handleChangeEvent.bind(this)}> update </button>
</div>
);
}
}
export default Child;
view raw

Child.js

hosted with ❤ by GitHub

As you can see, parent’s state has sent to child component and becomes child’s props.Then on button click of Child component, we are calling the onNamceChange method passed as props of parent component, and that updates the the Parent’s state.

It should then look something like this :

Here’s the link to the repository that contains all the code required for this blog.

Written by 

Principal Architect at Knoldus Inc

2 thoughts on “How data is handled between Components in React (State vs Props)4 min read

Comments are closed.