DEV Community

Cover image for Memoization using React.useMemo()
Hardik Sharma
Hardik Sharma

Posted on

Memoization using React.useMemo()

First we need to understand what memoization is. Memoization is an optimization technique, in which we accelerate our programs by caching the results of heavy function calls for the same inputs.

In simple terms, for example we have an input say '2' and we pass it through our function which takes a lot of time to execute. Now, if we need to calculate the result for input '2' again then we need to perform the function again and it will again take that much time.

But not if we used memoization in the first go, if we memoize the output for '2' of that function then we just need to get that value from our memoized values and don't need to execute that function again for '2', which in term will save us the time it takes for execution, and will make our program much more optimized.

In this post we will understand how to use useMemo React hook

useMemo()

useMemo is a React Hook that lets you cache the result of a calculation between re-renders. It accepts 2 arguments- a function that computes a result, and the depedencies array:


const memoizedValue = useMemo(calculateValue, dependencies)

Enter fullscreen mode Exit fullscreen mode

During initial rendering, useMemo(calculateValue, dependencies) invokes calculateValue, memoizes the calculation result, and returns it to the component.

If the dependencies don't change during the next renderings, then useMemo() doesn't invoke calculateValue, but returns the memoized value.

But if the dependencies change during re-rendering, then useMemo() invokes calculateValue, memoizes the new value, and returns it.


const memoizedResult = useMemo(() => {
  return heavyFunction(A, B);
}, [A, B]);

Enter fullscreen mode Exit fullscreen mode

In this case we have two dependencies A and B, so for the first render it will let the heavyFunction run to get the output, but in the re-renders if the dependencies don't change then it'll not execute the function and will return the memoized value.

Example

Let's take example of a classic recursion problem of calculating a factorial.

Image description

In factorial we often have the same input and without memoization the function always keeps on going to calculate the result, but if we memoize the output for a value and return that then we will save a lot of recursion cycles and will just return the memoized value at that point only.


function fact(n) {
  if(n <= 0){
    return 1;
  }
  return n * fact(n - 1);
}

Enter fullscreen mode Exit fullscreen mode

So this is a simple implementation of factorial of a number n using recursion.

Now, if we have a whole component for this:


import { useState, useMemo } from 'react';

export function CalculateFactorial() {
  const [number, setNumber] = useState(5);

  const factorial = useMemo(() => fact(number), [number]);

  const onChange = event => {
    setNumber(Number(event.target.value));
  };

  return (
    <div>
      Factorial of 
      <input type="number" value={number} onChange={onChange} />
      is {factorial}
    </div>
  );
}

function fact(n) {
  console.log('factorial called!');
  if(n <= 0){
    return 1;
  }
  return n * fact(n - 1);
}
Enter fullscreen mode Exit fullscreen mode

Every time you change the value of the number, factorial called! is logged to console. That's expected.

However, if we Re-render without changing the number, factorial called! isn't logged to console because useMemo(() => fact(number), [number]) returns the memoized factorial calculation. And hence saving us from calling the function again and recalculating.

useMemo() is a Hook, so you can only call it at the top level of your component or your own Hooks. You can’t call it inside loops or conditions.

I hope now you understand how useMemo works in React.
Thanks for reading.

Top comments (0)