How to use useMemo hook in React?

The useMemo is a caching hook in React. Memoization or cache a calculated value to avoid recalculation. Recalculate only when its dependencies update.

useMemo() syntax:

const cachedValue = useMemo(() => computeExpensiveValue(a, b), dependencies);

useMemo() accepts 2 arguments — a function computeExpensiveValue that compute and returns a value and the depedencies array:

How useMemo() works?:

  • On the first rendering, useMemo invokes computeExpensiveValue function and caches the calculated value, and returns it to the component.
  • In the next rendering, if the dependencies do not change, then useMemo() does not invoke computeExpensiveValue and returns the cached value
  • If the dependencies change in the next rendering, then useMemo() invokes computeExpensiveValue and cache the new value, and returns it.

Facts about useMemo():

  • It returns a value and not a function
  • Spreaded object inside dependencies does not work
  • It is difficult to know which dependencies cause re-calculation. We have a few workarounds like these: https://www.npmjs.com/package/@simbathesailor/use-what-changed
  • We should not overuse useMemo. In basic Big O(n) cases, we should avoid using useMemo

Example usage of useMemo():

import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";


const computeExpensiveValue = (num) => {
  console.log("Calculating...");
  for (let i = 0; i < 1000000000; i++) {
    num += 1;
  }
  return num;
};

const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const calculation = useMemo(() => computeExpensiveValue(count), [count]);

  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };

  return (
    <div>
      <div>
        <h2>My Todos</h2>
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
        <button onClick={addTodo}>Add Todo</button>
      </div>
      <hr />
      <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {calculation}
      </div>
    </div>
  );
};