React useMemo Hook to optimize your code

Sanjar Kairosh
November 30th, 20203 min read
Photo by Michael Dziedzic on Unsplash

michael-dziedzic-nLFqr9Mr9H8-unsplash.jpg

Photo by Michael Dziedzic on Unsplash

Memoization is the technique of storing the results of computationally expensive operations. When the operation is invoked again with similar inputs, the stored/cached results are returned, rather than executing the function anew.

In React, memoization can be utilized to optimize calculations every time a component is updated and re-rendered.

UseMemo is a React hook that was made exactly for that.

const memoizedValue = React.useMemo(() => computeSomething(a,b),[a,b]);

useMemo receives two arguments.

The first is the expensive function to be executed, and the second is an array of dependencies. Whenever at least one of the dependencies updates between renders, useMemo is bound to call the function, and return a new updated version of memoizedValue.

On every new render, useMemo will compare its dependencies with the previous render. If no changes between any dependencies is observed, useMemo will return the previous, memoized value, and no expensive calculation will need to take place.

If an empty dependencies array [] is provided, useMemo will only execute the function once on the very first render of the component, while referring to the memoized value for the remainder of the component’s lifecycle.

Good Use Case For useMemo

useMemo is especially useful when you are dealing with potentially large lists of items.

For example, upon receiving a large list of items as a response from a third-party API, you could map the items to react components to display as some information cards.

The mapping function would be defined inline within a parent component.

const Grid = () => {
    const [items, setItems] = React.useState(initialState);

		const cards = items.map(item => {
        return <Card key={item.id}/>
    })

		return (
	        <div>
	            {cards}
	        </div>
	  )
}

Every time the Grid component updates, the mapping functions is executed, calculating and returning an array of Card elements. If we are dealing with a large number of items this could prove inefficient.

We need to map the items to the card elements only on the Grids initial render, or whenever the list of items changes. Any other updates to the Grid component should not trigger the mapping operation.

With the useMemo hook we can ensure that we “remember” the value of the cards variable, and only execute the mapping function upon any changes to items.

const cards = React.useMemo(() => {items.map(item => {
   return <Card key={item.id}/>})
}, [items]);

The only dependency is the state that is the array of items.


Don’t Overuse useMemo

It is best to first write your code without useMemo and only implement it upon revisiting the code. Implementing useMemo too often can harm the application.

This is because React is fast. It can usually cope with the execution of inline functions on every render. In most cases you should think carefully before introducing complexity to your code by implementing useMemo. The benefits may be negligible and your time could be spent improving other areas of your code.

The one clear situation in which useMemo improves the efficiency of a React application is when you are dealing with really expensive operations such as mapping large lists of items to children components.

Blogs

copyright ©2021 all rights reserved, Sanjar Kairosh
illusrations by icons8