Pure Components
React components let us split the UI into independent, reusable pieces, and think about each piece in isolation. React components can be defined by extending from React.Component Class or React.PureComponent Class.
We have created different Component classes until now and all these classes were extending React.Component Class.
There are few use cases where we can use React Pure Components.
Lets look at one example.
We are developing one application in which we are displaying the Reports. Let the reports be Employee Reports or Stock Market Reports.
For this assume that we have created GetReports Component Class.
This Component Class gets the Reports by Calling a Web API and in the UI, we will have one Reload button using which user can reload the Reports so that he will get Updated Reports Data.
Now we have another Component which will be used to show if there are changes to the Reports Data. Lets say for every 5 seconds, this Component sends a request to the Web API and get the flag which tells whether there are any changes are not. If there are any changes, we will show a notification to the User, so that using Reload button user can get the updated Reports.
Lets open Index.js file from our demo-project
Lets create two Component Classes. One is DetectChanges Component Class and Other one is Reports Component Class. I have the Code handy and Pasting it here.
class ChangeDetection extends React.Component {
constructor(props) {
super(props);
this.state = {
employeeCount:0
};
setInterval(() => {
fetch("https://localhost:44306/api/Employee")
.then(res => res.json())
.then(
(result) => {
this.setState({
employeeCount: result.length
});
}
);
}, 5000);
}
render() {
return (
<div>
<h2>Welcome to Pure Component Demonstration...</h2>
<p>
<label>Number of Employees are : <b>{this.state.employeeCount}</b></label>
</p>
</div>
);
}
}
class Reports extends React.Component {
constructor(props) {
super(props);
this.state = {
employees:[]
};
}
componentDidMount=() => {
this.getEmployees();
}
getEmployees() {
fetch("https://localhost:44306/api/Employee")
.then(res => res.json())
.then(
(result) => {
this.setState({
employees: result
});
}
);
}
loadEmployees=()=>{
this.getEmployees();
}
render() {
return (
<div>
<h2>Employees Data...</h2>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Location</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
{this.state.employees.map(emp => (
<tr key={emp.Id}>
<td>{emp.Id}</td>
<td>{emp.Name}</td>
<td>{emp.Location}</td>
<td>{emp.Salary}</td>
</tr>
))}
</tbody>
</table>
<p>
<button onClick={this.loadEmployees}>Reload</button>
</p>
</div>
);
}
}
class App extends React.Component{
constructor(props){
super(props);
}
render(){
return(
<React.Fragment>
<ChangeDetection></ChangeDetection>
<Reports></Reports>
</React.Fragment>
)
}
}
const element=<App></App>
ReactDOM.render(element,document.getElementById("root"));
Save the Changes, Navigate to the Browser and we can see the Output.
We might feel that our code is working fine and we are getting the Results. But there are few issues with the code we have written here. Lets understand that.
For every 5 seconds, our changeDetection Component is sending a Web API request, getting the data and setting into the State Object.
Each time when we set the data into our state object or when we assign the property values, the component gets re-rendered.
Right now we have five employees data that is being shown. We have not added any new record . so each time when the ChangeDetection Component sends the request to Web API, it gets the Count as 5 but what happens is as we are setting the Data into state object , though it is the same data that means the Employee Count is 5 but still our component gets re-rendered. Lets add an alert in the render method of ChangeDetection Component, Save the Changes and navigate to the browser.
We can see that for every 5 seconds we get that alert notification. That means our component is getting re-rendered though there is no change in the data. That is because our Component is not Pure.
In order to avoid re-rendering of our ChangeDetectionComponent when there are no changes to the state data, we will make ChangeDetection Component as Pure.
PureComponent is similar to Component. The difference between them is that Component doesn’t implement shouldComponentUpdate(), but PureComponent implements it with a shallow comparison of properties and state data.
PureComponent’s shouldComponentUpdate() method returns true or false If the previous state and props data is the same as the next props or state, resulting the component is not Re-rendered.
If our React component’s render() function renders the same result given the same props and state, we can use React.PureComponent for a performance boost.
Lets go to ChangeDetection Component Class, instead of extending it from react.Component Class, extend it from React.PureComponent Class. Save the Changes, navigate to the browser. We can observe that we will not get the alert Notification repeatedly.
That is because there is no change in the Employee Count so that Component has no need to re-render.
Lets go to our Web API and add a record to our list. Build this Project. Lets go to our React Application. Now we will get the Alert notification because the count value is changed.
Now we can click on the Reload button in the Reports Component to get the New Employee Record.
React Components re-renders in the following scenarios:
1. “setState” is called in Component
2. “props” values are updated
3. this.forceUpdate() is called
In the case of Pure Components, the React components do not re-render blindly without considering the updated values of React “props” and “state”. If updated values are the same as previous values, render is not triggered.
React.PureComponent’s shouldComponentUpdate() performs only shallow comparison of the data. If data is either of type Objects or complex data structures, it may result in wrong rendering behaviors.
Now the question is what is Shallow Comparison?
Shallow compare checks for equality. When comparing values of type number or string it compares their values.
When comparing objects, it checks whether both the objects are pointing to the Same location or not. The Property Values of the Objects are not Compared.
That means if we have two objects named emp and emp1, and if we shallow Compare them, then it returns false.
let emp={
Id:101,
Name:’Pragim’};
let emp1={
Id:101,
Name:’Pragim’}
But if we assign emp to emp1 and do the Comparison, then it returns true.
let emp={
Id:101,
Name:’Pragim’};
let emp1=emp;
Lets go to our ChangeDetection Component Class, to the state object, lets add one employee object.
In setInterval method, though we assign the same object to the employee property of the state object, still we get the Alert Notification. Its because of the Shallow Comparison. Because it looks for the object which is holding the address but not the same values.
Now lets assign the same state object employee property. Save these changes, navigate to the browser. We can see that we don’t get the Alert Notification recurrently.
Pure Components are introduced for performance enhancement. You can use this optimization to improve the performance of your components. But remember that it works well provided our state and props are Primitive types only but not reference types like object or Array.
Video Reference:
© 2020 Pragimtech. All Rights Reserved.