reactjs
/

React useMemo Hook – Optimizing Performance

Last Sync: Today

On this page

7
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

reactjs

React useMemo Hook – Optimizing Performance

What is useMemo?

The useMemo hook is a built-in React hook that lets you cache the result of a calculation between re-renders. It is primarily used for performance optimization by ensuring that expensive logic only runs when its dependencies change.

Basic Syntax

React JSXRead-only
1
import { useMemo } from 'react';

const cachedValue = useMemo(() => {
  // 1. Calculate something expensive here
  return computeExpensiveValue(a, b);
}, [a, b]); // 2. Only re-run if 'a' or 'b' change

Expensive Calculation Example

Without useMemo, every time a component re-renders (even due to unrelated state changes), all logic inside the component body runs again. In the example below, filtering a large list is wrapped in useMemo to prevent lag when typing in an unrelated input field.

React JSXRead-only
1
import { useState, useMemo } from 'react';

function TodoList({ todos, tab }) {
  const [theme, setTheme] = useState('light');

  // This calculation is cached!
  const visibleTodos = useMemo(() => {
    console.log('Filtering todos...');
    return todos.filter(todo => todo.tab === tab);
  }, [todos, tab]); 

  return (
    <div className={theme}>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </div>
  );
}

When to Use useMemo

  • Expensive Calculations: When a function takes significant time to execute (e.g., processing thousands of data points).
  • Referential Integrity: When passing objects or arrays as props to a memoized child component (React.memo) to prevent unnecessary renders.
  • Dependency for other Hooks: When an object or array is a dependency for useEffect or another useMemo.

Comparison: useMemo vs useCallback

FeatureuseMemouseCallback
ReturnsThe result of the function (Value)The function itself
PurposeCache a calculated valueCache a function definition
Usageconst val = useMemo(() => compute(), [d])const fn = useCallback(() => compute(), [d])

Common Pitfalls

React JSXRead-only
1
// ❌ Wrong: Using useMemo for everything
// This adds overhead without performance gains
const name = useMemo(() => "John", []); 

// ✅ Correct: Only use for heavy logic
const sortedData = useMemo(() => [...data].sort(), [data]);

// ❌ Wrong: Side effects inside useMemo
useMemo(() => {
  console.log('I should be in useEffect!');
  window.localStorage.setItem('key', value);
}, [value]);

Best Practices

  • Measure first: Only optimize if you notice performance issues.
  • Keep it pure: The function inside useMemo should not have side effects.
  • Verify dependencies: Ensure all variables used inside the function are in the dependency array.
  • Readability: Don't sacrifice clean code for micro-optimizations that don't impact the user.

Try it yourself

import React, { useState, useMemo } from 'react';

const ExpensiveCalculation = () => {
  const [count, setCount] = useState(0);
  const [otherState, setOtherState] = useState(0);

  // Simulating a heavy calculation
  const expensiveValue = useMemo(() => {
    console.log('Calculating...');
    let num = 0;
    for (let i = 0; i < 1000000000; i++) {
      num += 1;
    }
    return count * 2;
  }, [count]);

  return (
    <div style={{ padding: '20px' }}>
      <h2>useMemo Demo</h2>
      <p>Expensive Value (2 * {count}): {expensiveValue}</p>
      
      <button onClick={() => setCount(c => c + 1)}>
        Increment Count (Slows because of logic)
      </button>
      
      <div style={{ marginTop: '10px' }}>
        <button onClick={() => setOtherState(s => s + 1)}>
          Update Other State (Fast! No re-calculation)
        </button>
        <p>Other State: {otherState}</p>
      </div>
    </div>
  );
};

export default ExpensiveCalculation;

Test Your Knowledge

Q1
of 3

What is the primary purpose of useMemo?

A
To synchronize state with localStorage
B
To cache a function definition
C
To cache the result of an expensive calculation
D
To create a persistent ref
Q2
of 3

When does the function inside useMemo re-run?

A
Every time the component re-renders
B
Only when dependencies change
C
Only on mount
D
When the browser window is resized
Q3
of 3

What happens if you leave the dependency array empty []?

A
It re-runs on every render
B
It throws a syntax error
C
It runs only once on mount
D
It never runs

Frequently Asked Questions

Does useMemo run on every render?

No. It only runs the function during the initial render and subsequently only when one of the dependencies in the array has changed.

Can I use useMemo for data fetching?

No. Data fetching is a side effect and should be handled in a useEffect hook or using a library like TanStack Query.

Is useMemo guaranteed to stay in memory?

Not strictly. React may occasionally discard the cache and recompute the value to free up resources, though this is rare.

Previous

react use ref

Next

react use callback

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.