Before digging into the PureCompoment thoroughly let's understand the difference between React component and PureComponent
NOTE: Considering you have basic knowledge of react.
In React Component, If you want to optimize performance then we have to implement shouldComponentUpdate lifecycle method where we can add condition check to see is props or state has been different from previous ones or not If it changed then only we will return true in shouldComponentUpdate method which will force to call render method otherwise render will get called every time props or state changed.
What PureComponent makes different from Component?
If you are extending the PureComponent class then you don't need to take care of shouldComponentUpdate lifecycle method. PureComponent itself takes care by shallow checking states and props. If it finds states and props are different from the previous state and props then only it calls render method else not.
What does shallow check mean?
Shallow compare does check for equality. When comparing primitive values (numbers, strings) it compares their values. When comparing nonprimitive like objects or arrays, it does not compare their's attributes - only their references are compared
For eg., If you have an array and you are pushing element to an existing array then PureComponent does not trigger render method because as per PureComponent there is no change happened because reference is still the same
Let's go by example
import React, { PureComponent } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends PureComponent {
constructor() {
super();
this.state = {
personArr: [
{
name: "abc",
age: "22 years",
gender: "male"
},
{
name: "pqr",
age: "23 years",
gender: "female"
},
{
name: "mno",
age: "24 years",
gender: "male"
}
]
};
}
addPerson() {
var persons = this.state.personArr;
persons.push({
name: "xyz",
age: "32 years",
gender: "male"
});
this.setState({
perosnArr: persons
});
}
render() {
const persons = this.state.personArr.map((person, index) => {
return (
<section>
<div>
<label>Name:</label> {person.name}
</div>
<div>
<label>Age:</label>
{person.age}
</div>
<div>
<label>Gender:</label>
{person.gender}
</div>
</section>
);
});
return (
<div className="App">
<button onClick={() => this.addPerson()}>Add person</button>
{persons}
</div>
);
}
}
render(<App />, document.getElementById('root'));
As you can see in the above code we are rendering a person's array and also we have added person button which pushing person object to an existing array.
so, Here PureComponent not let render method run because here an array is a non-primitive type so reference has been checked.
Here I think you might be thinking why PureComponent only checks the reference, not internal attributes because if react implements this logic then it's going to be a very expensive operation performance-wise.
Still, you want to run the render method after pushing element to an array then you should not mutate existing array, even react suggest should not mutate existing element.
For eg.
addPerson(){
const perosnArr = this.state.personArr;
perosnArr.push({
name: "xyz",
age: "32 years",
gender: "male"
})
this.setState({
perosnArr: {...personArr}
})
}
As you can see above I am not mutating existing array, I have created a new array using spread operator now the reference is different for old and new array so now render method will trigger.
Please check the example here
Top comments (0)