Pure Component in React.js


We have a lifecycle method called shouldComponentUpdate which by default returns true (Boolean) value.

The purpose of the shouldComponentUpdate is we can custom implement the default behavior and decide when react should update or re-render the component.

Generally we use state or props value to decide the update cycle. React has now provided us a PureComponent which does the comparison of state and props to decide the update cycle. We don’t need to override shouldComponentUpdate if we extend class with PureComponent.

React does the shallow comparisons of current state and props with new props and state to decide whether to continue with next update cycle or not.

This helps in improving the performance of the application. But we should extend the class with PureComponent only when it makes sense comparing every state and props. Else we can implement the shouldCompnentUpdate at our own if all state and props comparison is not required.

This extend PureComponent applies to only stateful class based compnents. For functional components we can use pure function as shown below −

Example with stateless component

import { pure } from ‘recompose’;
export default pure ( (props) => {
   //custom code
   return ‘something useful’ ;// your code
})

Example with stateful component

import React, {PureComponent} from ‘react’;
export default class Test extends PureComponent{
   render(){
      return ‘’;
   }
}

As PureComponent does shallow comparison of state and props objects and so there is a possibility that if these objects contains nested data structure then PureComponent’s implemented shouldComponentUpdate will return false . It can even skip the update of whole subtree of children of this component.

In this scenario, child elements should also be Pure then.

So nested data structure comparison does not works well with PureComponent. It works only if the state and props are simple objects.

Components can be termed as pure if they return same output for same input values at any point of time.

If state or props references new object, PureComponent will re-render every time.

Objects should be modified immutably to make update successfully using PureComponent

We can use forceUpdate to manually re-render even if shouldComponentUpdate fails. Use imutable.js if we have nested objects in shallow comparison .

Example

class Test extends React.PureComponent {
   constructor(props) {
      super(props);
      this.state = {
         taskList: [
            { title: 'excercise'},
            { title: 'cooking'},
            { title: 'Reacting'},
         ]
      };
   }
   componentDidMount() {
      setInterval(() => {
         this.setState((oldState) => {
            return { taskList: [...oldState.taskList] }
         });
      }, 1000);
   }
   render() {
      console.log(“taskList render called”);
      return (<div>
         {this.state.taskList.map((task, i) => {
            return (<Task
               key={i}
               title={task.title}
            />);
         })}
      </div>);
   }
}
class Task extends React.Component {
   render() {
      console.log(“task added”);
      return (<div>
         {this.props.title}
      </div>);
   }
}
ReactDOM.render(<Test />, document.getElementById('app'));

We have manually triggered a prop change call from componentDidMount after every second just to showcase how each task gets rendered every time.

Please check console log in browser.

Because Task component is not extending the PureComponent. React does not know what is changed so its rendering the Task every time.

So now just change Task component with below line

Export default class task extends PureComponent => It solves the multiple rendering of Task and prevents unnecessary render if no new task is added.

Updated on: 04-Sep-2019

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements