In this article, we are going to discuss about Pure components in React JS, what is pure functions & how to convert React components into a Pure components.
What is Pure Functions?
In Javascript, when functions returns same output when same input is passed is called Pure functions. It is like returning same data for same input. So in pure function output only depend on its input arguments. Pure functions does not produced any side effects as well. In past you may have already created so many pure function.
For example:
functionAdd(num1,num2){
returnnum1+num2;
}
If we call the aboveAdd(2,2)
function it will always return 4 as output. So if you call the above function with same input parameters multiple number of time it will always returns 4 output. Due to this pure function can optimize and improve the performance of function.
Pure functions in React
We know that in React we can create a component in two different ways i.e one is Class component/ Stateful component and another is Functional component/Stateless component. A React component can be considered pure if it renders the same output for the same state and props.
We can convert component to pure component as below:
- For class components react provides
React.PureComponent
base class. - For Functional component react provides
React.memo
HOC (Higher Order Component).
React.PureComponent
When a class component extendsReact.PureComponent
base class then React treated the component as Pure component. The major difference betweenReact.Component
class andReact.PureComponent
is the implementation ofshouldComponentUpdate()
.InReact.Component
shouldComponentUpdate() will always returns true on the other hand inReact.PureComponent
it will compare the current state and props with new state and props.
AsReact.PureComponent
implementsshouldComponentUpdate()
method for Pure component which will improve performance and optimize rendering. But the point here is that it is only doing the shallow comparison so if you have very complex nested object then it may give you false result.
So let's create simple class component as shown below:
importReact,{Component}from"react";
classPureClassComponentextendsComponent{
constructor(){
super();
this.state={
name:"React JS"
};
}
changeName=()=>{
this.setState({name:"React JS"});
};
render(){
console.log("FirstComponent -- Render method called");
return(
<div>
<p>Nameis:{this.state.name}</p>
<buttononClick={this.changeName}>ChangeName</button>
</div>
);
}
}
exportdefaultPureClassComponent;
In the above component when we click on button then we are setting the same value to name in the state. But interesting thing is that even if we are setting same value it will always re-render the component.
Here are the Pure components comes into picture. Pure component compare the current state with new state and current props to new props whenever thesetState()
method is called. So this will help to reduce the unnecessary calls torender()
method.
Now just import PureComponent class from react library and extend current component with PureComponent class and see the output in console.
Whenever we click onChange Name
button we are assigning same value to state but it is not calling render method again and again.
React.memo
React.memo
is nothing but a Higher Order function (HOC).React.memo
is similar toReact.PureComponent
and it is for functional component instead of class component. You can wrap your functional component when component renders same output with same props passed. Due to this it will improve the performance and optimize the rendering.
React.memo
only works when props of components changes. It means that if you are using state usinguseState
hook in functional then for every state change it will render the component. Similar toReact.PureComponent
it is doing shallow comparison of props.
React.memo
takes a first argument as component and returns a special kind of React component.
For demo purpose I have create simple counter app as shown below.
CustomLabel.js
importReactfrom"react";
exportdefault({name})=>{
return(
<>
{console.log("CustomLabel component render")}
<label>
<b>{name}</b>
</label>
</>
);
};
CounterComponent.js
importReact,{useState}from"react";
importCustomLabelfrom"./CustomLabel";
constCounterComponent=()=>{
const[counter,setCounter]=useState(0);
return(
<div>
<CustomLabelname="Simple Counter app"/>
<p>Counteris:{counter}</p>
<buttononClick={()=>setCounter(counter+1)}>Click</button>
</div>
);
};
exportdefaultCounterComponent;
Here I have created two components i.e CounterComponent and CustomLabel component. CustomLabel component accepts name as prop and display it in label tag. In CustomLabel component, we have added console.log() so that we can see how many times the component is getting render. Whenever you click on button to increase count it will re-render CustomLabel Component.
Now the 'React.memo' comes in picture. So wrap the CustomLabel component inside the 'React.memo' HOC and test the application again. You will see it renders the CustomLabel component only once because the name prop is remains same on every button click.
CustomLabel.js
importReact,{memo}from"react";
constCustomLabel=({name})=>{
return(
<>
{console.log("CustomLabel component render")}
<label>
<b>{name}</b>
</label>
</>
);
};
exportdefaultmemo(CustomLabel);
Conclusion
In this article, I have explained about Pure components in React JS and also discussed how to convert Class and Functional component into Pure components.
I really hope that you enjoyed this article, share it with friends and please do not hesitate to send me your thoughts or comments.
You can follow me on twitter@sumitkharche01
Happy Coding!
Thanks, is my first article reading from you. Gonna check the other 3. Awesome explanation.