Introduction to useMemo() Hook In ReactJS

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

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,

import React, { useState } from 'react'  
  
function RandomWords() {  
    const [count, setCount] = useState(0)  
    const [wordIndex, setWordIndex] = useState(0)  
  
    const words = ['This', 'is', 'React', 'Application', 'for', 'Testing', 'By', 'Priyanka']  
    const word = words[wordIndex]  
  
    const computeLetterCount = (word) => {  
        let i = 0;  
        while (i < 200000000) i++  
        console.log(i)  
        return word.length;  
    };  
  
    const letterCount = (word) => { computeLetterCount(word) };  
    return (  
        <div>  
            <div style={{ padding: '15px' }}>  
                <h2>Compute number of letters (slow)</h2>  
                <p>"{word}" has {letterCount(word)} letters</p>  
                <button  
                    onClick={() => {  
                        const next = wordIndex + 1 === words.length ? 0 : wordIndex + 1;  
                        setWordIndex(next);  
                    }}  
                >  
                    Next word  
                </button>  
  
                <h2>Increment a counter (fast)</h2>  
                <p>Counter: {count}</p>  
                <button onClick={() => setCount(count + 1)}>Increment</button>  
            </div>  
        </div>  
    )  
}  
  
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,

import React, { useState,useMemo } from 'react'  
  
function RandomWords() {  
    const [count, setCount] = useState(0)  
    const [wordIndex, setWordIndex] = useState(0)  
  
    const words = ['This', 'is', 'React', 'Application', 'for', 'Testing', 'By', 'Priyanka']  
    const word = words[wordIndex]  
  
    const computeLetterCount = (word) => {  
        let i = 0;  
        while (i < 200000000) i++  
        console.log(i)  
        return word.length;  
    };  
  
    const letterCount = useMemo(() => computeLetterCount(word), [word]);  
  
    return (  
        <div>  
            <div style={{ padding: '15px' }}>  
                <h2>Compute number of letters (slow)</h2>  
                <p>"{word}" has {letterCount} letters</p>  
                <button  
                    onClick={() => {  
                        const next = wordIndex + 1 === words.length ? 0 : wordIndex + 1;  
                        setWordIndex(next);  
                    }}  
                >  
                    Next word  
                </button>  
  
                <h2>Increment a counter (fast)</h2>  
                <p>Counter: {count}</p>  
                <button onClick={() => setCount(count + 1)}>Increment</button>  
            </div>  
        </div>  
    )  
}  
  
export default RandomWords 

Now the output will be as below,

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?

useCallbackuseMemo
Returns a memoized callbackReturn a memoized value
It returns referential equality between renders for functionsIt returns referential equality between renders for values
It returns the function when the dependencies changeIt 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.

In the next article, we will learn about thee useRef() hooks and their use in ReactJS.

Any question or feedback or suggestion, please do comment and let me know.

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s