useMemo - React Hooks Series
Published: 2021-06-28 02:57:36

Welcome back to the series of **React Hooks**.

**Series path**

- [useState](https://pratapsharma.io/use-state-react-hook)
- [useEffect](https://pratapsharma.io/use-effect-react-hook)
- useMemo

The main objective will be to explore how re-rendering works in React, why that is a critical factor for React applications, and how the `useMemo` hook can leverage it to build a performance boost in your applications. We will also see when `useMemo` can cause performance issues.

## What is `useMemo` hook?

`useMemo()` is a built-in React hook that accepts two arguments — a function compute that computes a result and the dependencies array:

```jsx
const memoizedResult = useMemo(compute, dependencies);
```

Let us try to get the essence of the `useMemo` hook. During the first rendering, `useMemo(compute, dependencies)` invokes the `compute` function, which is the first argument, memoizes the calculation result, and returns it to the component.

If during the next renderings the dependencies change, then `useMemo()` invokes `compute`, memoizes the new value, and returns it. But if dependencies don't change during re-rendering, then `useMemo()` doesn't invoke `compute` but returns the **memoized** value.

## When to Use `useMemo`?

The basic and first step is to write the code first and then revisit it to see if any optimization can be made.

> Implementing `useMemo` too often in an application can harm the performance.

When looking to implement `useMemo`, you can check with profiling tools in the debugger to identify any expensive performance issues. By expensive, I mean if the application is consuming a lot of resources (memory). It makes sense to memoize with `useMemo` only if you declare a large number of variables in a function at render.

## Example

A component `<ComputeFactorial />` calculates the factorial of a number introduced into an input field.

Here’s a possible implementation of `<ComputeFactorial />` component:

```jsx
import { useState } from "react";

export const ComputeFactorial = () => {
  const [number, setNumber] = useState(1);
  const [inc, setInc] = useState(0);

  const factorial = getFactorialOf(number);

  return (
    <div>
      Factorial of
      <input
        type="number"
        value={number}
        onChange={(event) => setNumber(Number(event.target.value))}
      />
      is {factorial}
      <button onClick={() => setInc((i) => i + 1)}>Force Re-render</button>
    </div>
  );
};

function getFactorialOf(n) {
  console.log("getFactorialOf(n) is called!");
  return n <= 0 ? 1 : n * getFactorialOf(n - 1);
}
```

Every time the input value is changed, the factorial is calculated using`getFactorialOf(n)` and '`getFactorialOf(n)` is called!' is logged to console.

On the other hand, each time you click the `Force Re-render` button, the `inc` state value is updated. Updating the `inc` state value triggers `<ComputeFactorial />` component to re-render. When a component is re-rendered, the factorial is recalculated again — '`getFactorialOf(n)` is called!' is logged to console.

How can you memoize the factorial calculation when the component re-renders? Welcome `useMemo()` hook!

By using `useMemo(() => getFactorialOf(number), [number])` instead of simple `getFactorialOf(number)`, React memoizes the factorial calculation.

Let’s improve `<ComputeFactorial />` and memoize the factorial calculation:

```jsx
import { useState, useMemo } from "react";

export const ComputeFactorial = () => {
  const [number, setNumber] = useState(1);
  const [inc, setInc] = useState(0);

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

  return (
    <div>
      Factorial of
      <input
        type="number"
        value={number}
        onChange={(event) => setNumber(Number(event.target.value))}
      />
      is {factorial}
      <button onClick={() => setInc((i) => i + 1)}>Force Re-render</button>
    </div>
  );
};

function getFactorialOf(n) {
  console.log("getFactorialOf(n) is called!");
  return n <= 0 ? 1 : n * getFactorialOf(n - 1);
}
```

Every time the value of the number is changed, '`getFactorialOf(n)` called!' is logged to console, which is expected.

However, if you click Force Re-render button, '`getFactorialOf(n) is called!`' isn’t logged to console because `useMemo(() => getFactorialOf(number), [number])` returns the memoized factorial calculation. How cool is that!

## Wrapping up

This article explored the `useMemo` hook and when it is appropriate to use it in a React application.

We also see that `useMemo` helps in boosting the performance of an application by "remembering" or **memoizing** expensive functions and preventing a re-render every time there is a change in the application.

We also learnt that while using `useMemo` can improve the application's performance, overusing `useMemo` can slow down your application. This means the more `useMemo` hook is used, and the memory has to be allocated for the memory.

If you have any questions, suggestions, corrections, I will look forward to it. Thank you for making it this far.

**Series path**

- [useState](https://pratapsharma.io/use-state-react-hook)
- [useEffect](https://pratapsharma.io/use-effect-react-hook)
- useMemo

💌 If you'd like to receive more tutorials in your inbox, you can sign up for the newsletter [here](https://pratap.substack.com).