useMemo() Hook In ReactJS

This article talks about the concept of useMemo() in React.

Introduction

 
In the previous article, we have learned about the concept of the useCallback() hook and how to implement that in React and why it is required. In this article, we will see another hook named useMemo() hook and its implementation.
 

useMemo() hook

 
The useMemo() hook allows you to memoize functions so that the function is prevented from being called on every render. It just includes a function containing an array of inputs which helps useMemo() hook to only recompute the memorized value when any of the input arrays have been changed.
 
Unlike useEffect() hook, the useMemo() hook does not trigger every time you change one of its dependencies.
 
The memoized function will always check to see if the dependencies need to be changed since the last render. If so, it executes the function and returns the result. And if it returns false, which dictates that nothing is changed, so it will return the cached result from the last execution. So, in this way useMemo() hook helps to improve performance in React application.
 
Syntax
  1. const memoizedValue = useMemo(() => computefunction(a, b), [a, b]);  
Where a,b can be values that need to be processed and a and b in square brackets are to specify when function need to be processed.
 
useMemo() hook memoize takes a function that needs to be memoized and an array of values that when changed, would invalidate the memoization.
 
Now let’s look at the demo and how it is used for performance optimization.
 
Create a component named RandomWords which will return words randomly on the click of a button,
  1. import React, { useState } from 'react'  
  2.   
  3. function RandomWords() {  
  4.     const [count, setCount] = useState(0)  
  5.     const [wordIndex, setWordIndex] = useState(0)  
  6.   
  7.     const words = ['This''is''React''Application''for''Testing''By''Priyanka']  
  8.     const word = words[wordIndex]  
  9.   
  10.     const computeLetterCount = (word) => {  
  11.         let i = 0;  
  12.         while (i < 200000000) i++  
  13.         console.log(i)  
  14.         return word.length;  
  15.     };  
  16.   
  17.     const letterCount = (word) => { computeLetterCount(word) };  
  18.     return (  
  19.         <div>  
  20.             <div style={{ padding: '15px' }}>  
  21.                 <h2>Compute number of letters (slow)</h2>  
  22.                 <p>"{word}" has {letterCount(word)} letters</p>  
  23.                 <button  
  24.                     onClick={() => {  
  25.                         const next = wordIndex + 1 === words.length ? 0 : wordIndex + 1;  
  26.                         setWordIndex(next);  
  27.                     }}  
  28.                 >  
  29.                     Next word  
  30.                 </button>  
  31.   
  32.                 <h2>Increment a counter (fast)</h2>  
  33.                 <p>Counter: {count}</p>  
  34.                 <button onClick={() => setCount(count + 1)}>Increment</button>  
  35.             </div>  
  36.         </div>  
  37.     )  
  38. }  
  39.   
  40. export default RandomWords  
The output will be displayed as below,
 
As we see that on click of any button all methods are rendered which reduces performance.
 
So here we will make use of useMemo() hook,
  1. import React, { useState,useMemo } from 'react'  
  2.   
  3. function RandomWords() {  
  4.     const [count, setCount] = useState(0)  
  5.     const [wordIndex, setWordIndex] = useState(0)  
  6.   
  7.     const words = ['This''is''React''Application''for''Testing''By''Priyanka']  
  8.     const word = words[wordIndex]  
  9.   
  10.     const computeLetterCount = (word) => {  
  11.         let i = 0;  
  12.         while (i < 200000000) i++  
  13.         console.log(i)  
  14.         return word.length;  
  15.     };  
  16.   
  17.     const letterCount = useMemo(() => computeLetterCount(word), [word]);  
  18.   
  19.     return (  
  20.         <div>  
  21.             <div style={{ padding: '15px' }}>  
  22.                 <h2>Compute number of letters (slow)</h2>  
  23.                 <p>"{word}" has {letterCount} letters</p>  
  24.                 <button  
  25.                     onClick={() => {  
  26.                         const next = wordIndex + 1 === words.length ? 0 : wordIndex + 1;  
  27.                         setWordIndex(next);  
  28.                     }}  
  29.                 >  
  30.                     Next word  
  31.                 </button>  
  32.   
  33.                 <h2>Increment a counter (fast)</h2>  
  34.                 <p>Counter: {count}</p>  
  35.                 <button onClick={() => setCount(count + 1)}>Increment</button>  
  36.             </div>  
  37.         </div>  
  38.     )  
  39. }  
  40.   
  41. export default RandomWords   
Now, the output we observe will be quite fast and it will only return delayed output for the first button rather than the second button.
 
So, the useMemo() hook should be used in the case where transforming API, fetching data from API, or any other operation where there are multiple operations going on a single page.
 

When to use useCallback() and useMemo()?

 
There are 2 main reasons why both hooks are built into React,
  1. Referential equality
  2. Computationally expensive calculations.

Difference Between useMemo() and useCallback() hook?

 
useCallback
useMemo
Returns a memoized callback
Return a memoized value
It returns referential equality between renders for functions
It returns referential equality between renders for values
It returns the function when the dependencies change
It calls the function when the value changes and return result
 

Summary

 
In this article, we have learned about useMemo() hook in React and how it can be used in the application. You can the download source code attached along with this article. In the next article, we will learn about thee useRef() hooks and their use in ReactJS.