Control rendering with React Memo
3 min read
Before React Hooks was introduced in React 16.8, we were switching between class- and function components. All the class components contained the state and the function components contained all the JSX and was managing the rendering of the UI.
One of the main benefits of the class component is that it contains the lifecycle hooks you can use to control the component like ComponentDidMount, ComponentDidUnmount, componentDidCatch. Class Components also contains the shouldComponentUpdate lifecycle hook, which is quite useful when you want to control the rendering of the component.
The virtual DOM behind React is comparing the state in the Node Tree, and when one JSX element is updated, then every child is updated as well.
The Virtual DOM is pretty fast and performant, so we usually don’t have to optimize the code for performance.
You will most likely have some components which rerenders unnecessarily, but the performance decrease will probably not affect your code or the user experience, and therefore you don’t have to worry at all. Otherwise React wouldn’t been very popular :-).
Eventually, you will find yourself implementing a component that contains so many child components where you need the features or functionality to control the rerendering.
shouldComponentUpdate() is used to control when a component should update. In the example below we check if not equal to “green”, and return the result which will determine if we can update the component. If the color is green, we will return false that will result in render() not being called and therefore not updating the component.
We will in the parent component implement Collection.js component, and add some simple buttons to demonstrate the behaviour.
Now this way of using shouldComponentUpdate was only for demonstration purposes and is not how you should approach conditional rendering.
With React 16.8 introducing hooks, you will then see multiple components that used to be class components, being written as a function component with a useState hook.
useEffect is used to control the common lifecycle hooks like componentDidMount, componentWillUnmount and componentDidUpdate but it does not contain a shouldComponentUpdate hook functionality like class components.
React.memo to the rescue!
React.memo, short for memoization, is a higher order component and will only update if the props has changed. On Wikipedia memoization is described as
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again
Now the code look likes this
Collection has now become CollectionMemo by composing it with React memo. Now CollectionMemo will only update when the props change.
How can i control updating the component based on specific passed props?
I’m glad you asked :-)
With React.memo you can pass a callback as a second argument where you will receive previous props and the next props and can with that knowledge determine if the component should update or not. Here you can add the logic to determine that.
In the areEqual function, if the prop is equal we return true stating that the props is the same and should not update. Otherwise we update the component to reflect the props. If you update the component by setting useState then the component will update regardless of the React.memo conditions.
Hope it was helpful to you!