The shouldComponentUpdate lifeCycle method
This method only exists as a performance optimization. Do not rely on it to “prevent” a rendering, as this can lead to bugs. The React legacy advise us to consider using the built-in PureComponent instead of writing shouldComponentUpdate() by hand.
When to use the shouldComponentUpdate() method?
The shouldComponentUpdate() method:
- is used in class components only,
- can be called when children components receive new state or props to declare specifically if the components should update or not depending on its own state and props,
- is invoked before rendering an already mounted component when new props or states are being received.
How does the shouldComponentUpdate() method works?
The shouldComponentUpdate() method:
- takes nextProps and nextState as arguments;
- compare the current props (this.props) to the next props (nextProps);
- determine if the component needs to update or not;
- return a boolean value (true or false) accordingly that tells React whether or not to update the component (render when true);
How to implement the shouldComponentUpdate() method?
- Declare the parent component, declare the child component and insert it in its parent.
- In the child component, below the constructor, declare the
shouldComponentUpdate()
method and pass itnextProps
andnextState
as arguments if the component receives props and have its own state. - Inside the method, if the component receives props, insert the condition when the true boolean is returned like
if (nextProps.propsName !== this.props.propsName) return true;
- If the component has its own state, insert the condition when the true boolean is returned like
if (nextState.stateProperty !== this.state.stateProperty) return true;
- Then add
return false
.
Code structure when the child component receives no props and has no state
To prevent a child component which receives no props and has no state to re-render, you just have to implement the shouldComponentUpdate function with no arguments passed and returning false only.
Remark: Passing nextProps and/or nextState as arguments when there are not props or state will throw an error in the console!
Code structure when the child component receives props but has not its own state
Pass netxProps as argument and insert the rendering condition based on the received props.
Remark: the below code is the standard one. The condition can be another one: refer to the given example whose condition is based on even numbers.
Note: Be careful when using the shouldcomponentUpdate() method, if this above code is inserted in a child component which has it’s own state, the component won’t be re-rendered when its state changes ! Do not forget to pass nextState as argument and to insert the condition based on the state as shown below.
Code structure when the child component receives props and has its own state
If the child component receives props and has its own state, use the below code structure.
Remark: The conditions can be others but be very careful and assure you not to forget/prevent important re-rendering.
In fact, if you are writing exactly the above code you have to stop and consider using the built-in PureComponent instead of writing shouldComponentUpdate() by hand.
Optimize the re-renders with the built-in React PureComponent
The built-in PureComponent prevent a child component rendering without leading to bugs. Use-it instead of writing a shouldComponentUpdate() method by hand.
When to use the PureComponent?
The PureComponent is used:
- in class components only,
- to prevent children components which receive props and have its own state to re-render because of parent.
How does the PureComponent works?
PureComponent performs a shallow comparison of props and state, and reduces the chance that you’ll skip a necessary update as when using the shouldComponentUpdate() method.
How to implement the PureComponent?
It is easy to implement the React PureComponent: no need to modify the inside child component code, no need to add a method.
- When declaring the class component, replace
extends React.
byComponentsextends React.PureComponent
. - Change the ComponentName into PureComponentName.
- Insert the PureComponentName in the parent component as you would have done for the ComponentName, no change except the name!
That’s all!
Write your first optimized re-renders child components with the below example
This example is based on a freeCodeCamp challenge I have modified by adding a third component having no state and receiving no props.
More information about the App we are going to code
In this example, there are three components : Controller, OnlyEvens and… NoChange (the one I have added).
- The Controller parent component:
- has a state property named value which is initialized with 0;
- contains a button which increment the state value by 1 every time it is clicked;
- contains a child component named OnlyEvens which receives a value (the state value property value) as prop;
- contains a child component named NoChange which does not receive any prop;
- re-renders every time its state is modified.
- The OnlyEvens child component:
- renders the value received as props in a paragraph;
- should updates only if the value of its new props is even.
- The NoChange child component:
- renders a text in a paragraph;
- has no state;
- receive no prop;
- will never be modified;
- has no reason to be re-rendered.
Let’s code the App step by step
Code the optimized re-renders App step by step
We consider that React as been installed or a new pen as been created on codepen.
- Create the HTML file, the element and add it the optimize id attribute to “attach” the React App (Controller component) rendering.
- Create the Controller component, declare its local state value property and initialize the value it with 0.
- In the render, insert the three elements:
- the button whose text is “Add”, on which is assign a onClick event which trigger the addValue event handler method (to be created),
- the OnlyEvens child component (to be created) which receives a prop named value whose value is the state property value,
- the NoChange child component (to be created).
- Declare the addValue method which update the state property value by adding 1, and bind it.
- Create the NoChange child component wich renders only a paragraph containing “Not re-rendered NoChange component” (no constructor needed).
- In the NoChange component above the render(), insert a shouldComponentUpdate() method to prevent it to re-render because of its parent Controller. As this component has neither state nor received props, pass no argument to the method and insert no rendering condition.
- Create the OnlyEvens child component which renders the received props value in a paragraph.
- In the OnlyEvens component above the render(), insert a shouldComponentUpdate() method to prevent it to re-render because of its parent Controller when received prop value ode. As the render must be done when the value is even, we use a rendering condition using the modulo operator because even numbers divided by 2 modulo will ever equals 0.
- Click the Add button and note that the number of click display is not updated when it is odd.
That’s all. Find the final code below.
The final code of the optimized re-renders App
In the pen inserted below, I have added some console.log to check everything is running well:
- A console.log inside the OnlyEvens shouldComponentUpdate() method displays ‘Should I update?’ and the number of clicks to control if the number is odd or even.
- A componentDidUpdate() lifcycle method has been added to every component to insert a console.log which appears only if the component is re-rendered. Note that the parent component is re-rendered every time the state is updated by clicking on the button. But, if everything is ok, the NoChange re-rendered should never appear while the Component re-rendered should appear only on even click number.
Click the Add button and watch the order of events in the browser’s or pen console as the lifecycle hooks are triggered.
Play with the below pen
Do not hesitate to comment and uncomment the shouldComponentUpdate() method in each child component to check the order of events in the pen console.
See the Pen
React tricks: Optimize class component Re-Renders with shouldComponentUpdate by Coding-Tricks (@coding-tricks)
on CodePen.
In conclusion
In this article we have learnt how to optimize children components re-renders in a class component with the shouldComponentUpdate() lifecyle method and the PureComponent.
In the next article Optimize react re-renders with react memo we will discover how to optimize children components re-renders in a functional component with React.memo.