React Mastery / Advanced React Hooks

useMemo Hook

React’s useMemo is a powerful tool for performance optimization. It allows you to memoize the result of a calculation between re-renders, ensuring that expensive logic only runs when absolutely necessary.


❓ What is useMemo?

useMemo is a React Hook that caches the return value of a function. Think of it as a way to "remember" a piece of data so you don't have to recalculate it every time the component updates.

Basic Syntax

const cachedValue = useMemo(() => calculateValue(a, b), [a, b]);
  • The Callback Function: A pure function that takes no arguments and returns the value you want to cache.

  • The Dependencies: A list of all reactive values (props, state, and variables declared inside your component) used inside the calculation.


🧐 Why use it?

In React, when a component's state or props change, the entire function body re-runs. If you have a complex calculation (like filtering a massive array or performing heavy math), running it on every single flicker of a UI change can lead to "jank" or lag.

Key Benefits:

  • Skipping expensive calculations: Only re-runs the code when inputs change.

  • Referential Identity: Prevents unnecessary re-renders of child components that rely on object or array props.


👀 How it Works (The Lifecycle)

  1. Initial Render: React calls your function and stores the result.

  2. Re-render (Dependencies unchanged): React ignores the function and returns the stored value from the previous render.

  3. Re-render (Dependencies changed): React executes the function again, stores the new result, and returns it.


✅ Practical Example

Imagine you are building a Product Dashboard. You have a list of 5,000 products, and you need to perform two tasks:

  1. Filter/Search through the products (Expensive).

  2. Toggle the Theme (Dark/Light mode) of the entire page (Cheap).

The Problem

Without useMemo, every time you toggle the Theme, React re-renders the component. This forces the computer to re-filter all 5,000 products, even though the product list hasn't changed at all. This makes the theme toggle feel laggy.

Scenario A: You type "Apple" in the search box

  1. The search state updates.

  2. React checks the dependency array: [products, search].

  3. Since search changed, React executes the Calculation Function.

  4. The list is filtered, and the UI updates.

Scenario B: You click "Toggle Theme"

  1. The isDarkMode state updates.

  2. React re-renders the component.

  3. React checks the dependency array: [products, search].

  4. Neither products nor search changed.

  5. React skips the calculation function and instantly returns the filteredProducts from the previous render.

  6. The theme changes instantly without the lag of re-filtering 5,000 items.


🔴 When to Avoid useMemo

Don't wrap everything in useMemo! Overusing it can actually hurt performance because the hook itself has a small memory and computational overhead.

  • Cheap calculations: If you’re just adding two numbers or concatenating a string, the overhead of useMemo is higher than the calculation itself.

  • Readability: It makes code more verbose. Only add it if you notice a performance bottleneck.

  • Incorrect Dependencies: If you forget a dependency, your value will be "stale" (it won't update when it should).

Pro Tip: Before reaching for useMemo, try to optimize by extracting components or passing children. Often, "state lifting" or "component composition" solves the performance issue more cleanly.


👉 useMemo vs. useCallback

These two are frequently confused. Here is the breakdown:

Feature

useMemo

useCallback

Returns

The result of a function (value).

The function itself (memoized).

Purpose

To avoid expensive calculations.

To avoid re-creating functions (useful for props).

Analogy

Storing the answer to a math problem.

Storing the formula to solve the problem.