Contents

Frontend Development › UI Frameworks & Components

memo, useMemo and useCallback

Skipping work when inputs haven't changed.

Also known as: React.memo, useMemo, useCallback, memoization in React, React memo

In React, a component re-renders when its parent re-renders, even when its own props haven’t changed. Memoization tells React to skip work when the inputs are the same. There are three tools:

ToolCachesSkips
React.memo(Component)The rendered output of a componentRe-rendering when props are shallowly equal
useMemo(() => compute(a, b), [a, b])A computed valueRecomputing it on every render
useCallback(fn, [deps])A function identityCreating a new function each render
const ProductList = React.memo(function ProductList({ products, onSelect }) { ... });

function Page({ products }) {
  const [query, setQuery] = useState("");
  const onSelect = useCallback((id) => navigate(`/p/${id}`), []);          // stable reference
  const visible = useMemo(() => products.filter(p => p.name.includes(query)), [products, query]);

  return <ProductList products={visible} onSelect={onSelect} />;
}

Why useCallback and useMemo matter for memo

React.memo compares props with === (shallowly). An object, array or function created inline is a new reference on every render, so memoization sees “changed” every time and does nothing:

<ProductList onSelect={(id) => navigate(id)} />      // new function each render: memo is defeated

Stabilizing references with useCallback and useMemo lets memo work.

Don’t do it by reflex

  • Memoization has a cost: comparing dependencies, holding cached values and extra code to read. For small components it can be slower than just re-rendering.
  • Measure first with the React DevTools Profiler (unnecessary re-renders). Optimize components that are actually slow.
  • Fix the structure first: move state down to the component that needs it, or pass children, which often removes the problem without any memoization.
  • Wrong or missing dependencies are bugs: a useMemo that doesn’t list a value it uses will return stale results (dependency array).
  • It’s a performance hint, not a guarantee. Your program must be correct even if React discards the cache.
  • Newer React tooling (the React Compiler) can add much of this memoization automatically. Check what your project uses before adding it by hand.

For caching expensive computations outside React, see memoization.