This is the fourth article of the React Tutorials series. The list of the previous articles is given below.
Today, we will learn about the Props and State in React. Props and State are used to store and follow the data in applications. In previous articles, we learned about multiple components, so if we are using the multiple components in our application, then sometimes we need to share the data between components. In such type of scenarios, we can use Props. Actually, Props are used to transfer the data from parent to child component. Let’s look at an example and learn how Props work.
Main.jsx
- import React from 'react';
- import Footer from '../footer/footer';
- import Header from '../header/header';
- class Main extends React.Component {
- constructor(){
- super();
-
- }
-
-
- render() {
- var employee={
- name:"Pankaj",
- project:"Lions Services",
- duration:"8 Months"
- }
- return (
- <div>
- <h3>This is main Component</h3>
- <Header empdetails={employee}></Header>
- </div>
- );
- }
- }
-
- export default Main;
header.jsx
- import React from 'react';
-
- class Header extends React.Component {
-
- constructor(){
- super();
- }
-
- render() {
-
- return (
- <div>
- <h2>This is header</h2>
- <h3> Employee: {this.props.empdetails.name}</h3>
- <h3> Project Name: {this.props.empdetails.project}</h3>
- <h3> Time Duration: {this.props.empdetails.duration}</h3>
- </div>
- );
- }
- }
-
- export default Header;
Output
To use a Property in component, just define the Property as an html attribute and assign the value to Props using “{}” curly braces.
In child component, we can access the Props value using the “this.props” keyword.
Default Props
In React, we can also define the default props for the component. Paste the following code into your “header.jsx” file and save the changes.
Header.jsx
- import React from 'react';
-
- class Header extends React.Component {
-
- constructor(){
- super();
- }
-
- render() {
-
- return (
- <div>
- <h2>This is header</h2>
- <h3> Employee: {this.props.empdetails.name}</h3>
- <h3> Project Name: {this.props.empdetails.project}</h3>
- <h3> Time Duration: {this.props.empdetails.duration}</h3>
- <ul>
- {this.props.skills.map((skill,i)=><li key={i}>{skill}</li>)}
- </ul>
- </div>
- );
- }
- }
-
-
- export default Header;
When you save the change, you will get the following error.
We get this error because in “Header.jsx”, we don’t have any “skills” Prop. In React, we can define the default Props so if we forget to assign the value of Props from the parent component, it will use the default values for the Props. Now, replace the code of “Header.jsx” with the following code.
- import React from 'react';
-
- class Header extends React.Component {
-
- constructor(){
- super();
- }
-
- render() {
-
- return (
- <div>
- <h2>This is header</h2>
- <h3> Employee: {this.props.empdetails.name}</h3>
- <h3> Project Name: {this.props.empdetails.project}</h3>
- <h3> Time Duration: {this.props.empdetails.duration}</h3>
- <ul>
- {this.props.skills.map((skill,i)=><li key={i}>{skill}</li>)}
- </ul>
- </div>
- );
- }
- }
-
- Header.defaultProps ={
- skills:["C#","MVC","Angular","Nodejs"]
- }
- export default Header;
The following will be our output.
PropTypes
Using propTypes in a component, we can define the validation for the properties of a component. That means we can define the datatype or required filed for the properties. Let’s take an example.
Main.jsx
- import React from 'react';
- import Footer from '../footer/footer';
- import Header from '../header/header';
- class Main extends React.Component {
- constructor(){
- super();
-
- }
- render() {
- var name="Pankaj";
- var age=23;
- var city="Alwar"
- return (
- <div>
- <h3>This is main Component</h3>
- <Header name={name} age={age} city={city}></Header>
- </div>
- );
- }
- }
-
- export default Main;
Header.jsx
- import React from 'react';
-
- class Header extends React.Component {
-
- constructor(){
- super();
- }
-
- render() {
-
- return (
- <div>
- <h2>This is header</h2>
- <h3>{this.props.name}</h3>
- <h3>{this.props.age}</h3>
- <h3>{this.props.city}</h3>
- </div>
- );
- }
- }
-
-
- export default Header;
When you save all of the above changes, you will get the following result.
Now, go to the “main.jsx” file and make any changes into “age” variable.
In the above screen, we can see that we changed the “age” variable from string to array type. So, the following will be the output.
In “Header” component, we don’t define any datatype and another validation for the properties, so we can pass any value to properties; but in a component, we can define the datatypes for properties. Now, replace the code of “Header.jsx” with the following code.
Header.jsx
- import React from 'react';
-
- class Header extends React.Component {
-
- constructor(){
- super();
- }
-
- render() {
-
- return (
- <div>
- <h2>This is header</h2>
- <h3>{this.props.name}</h3>
- <h3>{this.props.age}</h3>
- <h3>{this.props.city}</h3>
- </div>
- );
- }
- }
-
- Header.propTypes = {
- name: React.PropTypes.string.isRequired,
- age: React.PropTypes.number,
- city: React.PropTypes.string.isRequired
- }
- export default Header;
When you save the above changes, you will get the same result as previous.
But this time, you get some warning in console of the browser.
This warning says that “Header” requires the “age” property of number type but we are passing the “Age” property of “array” type. So, change the datatype of “age” variable from array to number in “Main” component and this warning will resolve.
Output
State
State is used to store the data into component. In other words, State is the place from where we get the data into our component. We always try to make the state-less component, because each component will render several lifecycle hooks that can affect the performance of component. So try to make a parent component and define all the states for that component.
Main.jsx
- import React from 'react';
- import Footer from '../footer/footer';
- import Header from '../header/header';
- class Main extends React.Component {
- constructor(){
- super();
- this.state={
- name:"Pankaj",
- age:23,
- city:"Alwar"
- }
- }
- render() {
-
- return (
- <div>
- <h3>This is main Component</h3>
- <h3>{this.state.name}</h3>
- <h3>{this.state.age}</h3>
- <h3>{this.state.city}</h3>
- </div>
- );
- }
- }
-
- export default Main;
Output
Above is a simple example of state in React, but why do we need state in React? Let’s take an example and understand the role of state into a React component. Replace the code of Main.jsx file with following code.
Main.jsx
- import React from 'react';
- import Footer from '../footer/footer';
- import Header from '../header/header';
- class Main extends React.Component {
- constructor(){
- super();
- console.log('constructor executed')
-
- this.state={
- name:"Pankaj",
- age:23,
- city:"Alwar"
- }
- this.number=1200;
- }
- componentWillMount() {
- console.log('componentWillMount executed')
- }
-
- componentDidMount() {
- console.log('componentDidMount executed')
- }
-
- componentWillReceiveProps(newProps) {
- console.log('componentWillReceiveProps executed')
- }
-
- shouldComponentUpdate(newProps, newState) {
- console.log('shouldComponentUpdate executed')
- return true;
- }
-
- componentWillUpdate(nextProps, nextState) {
- console.log('componentWillUpdate executed');
- }
-
- componentDidUpdate(prevProps, prevState) {
- console.log('componentDidUpdate executed')
- }
-
- componentWillUnmount() {
- console.log('componentWillUnmount executed')
- }
- changeData(){
- this.number=1823;
- console.log(this.number);
- }
-
- render() {
-
- return (
- <div>
- <h3>This is main Component</h3>
- <h3>{this.state.name}</h3>
- <h3>{this.state.age}</h3>
- <h3>{this.state.city}</h3>
- <h3>{this.number}</h3>
- <input type="button" onClick={()=>this.changeData()} value="change State"/>
- </div>
- );
- }
- }
-
- export default Main;
Output
Now, click on the “Change State” button; you will get the following output.
You can see that the value of number has been changed from 1200 to 1823 but View is not updated. Let’s make some changes into code and examine the result. Replace the below line of code into “chnageData” method.
this.setState({name: "Pankaj Choudhary"})
After making the above change, now click on the “Change State” button. This time, we will get the following output.
You can see that this time, View has been updated. So whenever state of the component is changed, it re-renders the component also. Here, a point to notice is that React doesn’t re-render the whole component, instead it only re-renders the updated section.
Here, I am using the “Google Chrome” browser. If you are using Chrome too, then go to the “Developer Tools” and enable the “Paint Flashing” option.
After enabling this feature, when any section of the screen will update, it will highlight the updated section. Now, click on the “Change State” button again and check the result.
You can see that only “Name” and “Number” section is updated because we changed these values only. So React only reflects the updated section instead of whole component, that makes it faster.
State-less Component:
In React, we can create State-less components. Let’s take an example of how to create it.
Main.jsx
- import React from 'react';
- import Footer from '../footer/footer';
- import Header from '../header/header';
- class Main extends React.Component {
- constructor(){
- super();
- this.state={
- name:"Pankaj",
- age:23,
- city:"Alwar"
- }
- this.number=1200;
- }
- changeData(){
- this.number=1823;
- console.log(this.number);
- this.setState({name: "Pankaj Choudhary"})
- }
-
- render() {
-
- return (
- <div>
- <h3>This is main Component</h3>
- <h3>{this.state.name}</h3>
- <h3>{this.state.age}</h3>
- <h3>{this.state.city}</h3>
- <h3>{this.number}</h3>
- <Header data="Header Component"></Header>
- <input type="button" onClick={()=>this.changeData()} value="change State"/>
- </div>
- );
- }
- }
-
- export default Main;
Header.Jsx
- import React from 'react';
-
- class Header extends React.Component {
-
- constructor(){
- super();
- }
-
- render() {
-
- return (
- <div>
- <h3>{this.props.data}</h3>
- </div>
- );
- }
- }
-
- Header.propTypes = {
- data: React.PropTypes.string.isRequired
- }
- export default Header;
Output
In “Header” component, we didn’t use the State; we only used Properties so we can change the “Header” component into a stateless component. If you want to make a component stateless, just make it a const function like below.
Header.jsx
- import React from 'react';
-
- const Header =(props)=> {
- return (
- <div>
- <h3>{props.data}</h3>
- </div>
- );
- }
-
- Header.propTypes = {
- data: React.PropTypes.string.isRequired
- }
- export default Header;
In the above code, we removed the “React.Component” class and converted the “Header” class to const function. Also, we removed the render function and write the return function only. So after making all the above changes, now our “Header” component is a stateless component.
Conclusion
In this article, we learned about React properties and State. In our next article, we will learn about Routing. If you have any queries or doubts, please mention them in the comments section.
You can download the latest source code of this project from GitHub. Given below is the link of repository.