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:
function Add(num1, num2){
return num1 + num2;
}
If we call the above Add(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 extends React.PureComponent
base class then React treated the component as Pure component. The major difference between React.Component
class and React.PureComponent
is the implementation of shouldComponentUpdate()
. In React.Component
shouldComponentUpdate() will always returns true on the other hand in React.PureComponent
it will compare the current state and props with new state and props.
As React.PureComponent
implements shouldComponentUpdate()
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:
import React, { Component } from "react";
class PureClassComponent extends Component {
constructor() {
super();
this.state = {
name: "React JS"
};
}
changeName = () => {
this.setState({ name: "React JS" });
};
render() {
console.log("FirstComponent -- Render method called");
return (
<div>
<p> Name is : {this.state.name} </p>
<button onClick={this.changeName}>Change Name</button>
</div>
);
}
}
export default PureClassComponent;
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 the setState()
method is called. So this will help to reduce the unnecessary calls to render()
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 on Change 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 to React.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 using useState
hook in functional then for every state change it will render the component. Similar to React.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
import React from "react";
export default ({ name }) => {
return (
<>
{console.log("CustomLabel component render")}
<label>
<b>{name}</b>
</label>
</>
);
};
CounterComponent.js
import React, { useState } from "react";
import CustomLabel from "./CustomLabel";
const CounterComponent = () => {
const [counter, setCounter] = useState(0);
return (
<div>
<CustomLabel name="Simple Counter app" />
<p>Counter is : {counter} </p>
<button onClick={() => setCounter(counter + 1)}>Click</button>
</div>
);
};
export default CounterComponent;
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
import React, {memo} from "react";
const CustomLabel=({ name }) => {
return (
<>
{console.log("CustomLabel component render")}
<label>
<b>{name}</b>
</label>
</>
);
};
export default memo(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!
Top comments (2)
Thanks, is my first article reading from you. Gonna check the other 3. Awesome explanation.
Very nice article brother.... Going to check other articles as well. Thanks for great explanation