Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

useMemo caches the result of a calculation between component renders. Use it when profiling shows that recalculating a value is meaningfully expensive, or when a calculated value needs a stable identity for a memoized child or another Hook. It is a performance optimization—not persistent storage—and React may discard its cache.

What does useMemo do?

useMemo remembers the value returned by a pure calculation. React runs that calculation during the initial render, then reuses the cached value on later renders while its dependencies remain unchanged. The Hook’s basic form is:

const cachedValue = useMemo(calculateValue, dependencies);

Call it at the top level of a function component or custom Hook. The calculation takes no arguments and returns the value to cache; React invokes it during rendering. For example, a component that filters a list might use:

const visibleItems = useMemo(
  () => filterItems(items, query),
  [items, query]
);

Without useMemo, the calculation would run whenever the component renders. With it, React can reuse the prior result if the listed inputs have not changed. It does not make the initial render faster.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What belongs in the dependency array?

Include every reactive value that the calculation reads: props, state, and variables or functions declared in the component body. React compares each dependency with its previous value using Object.is. The dependency list must be written inline and contain a constant number of items. See the React useMemo reference.

Omitting a value can leave the calculation using an outdated value. Adding a newly created object or function can make the calculation run again on every render, even when its contents appear unchanged.

Watch for objects and functions created during rendering

Each render creates a new identity for an object literal or inline function. In this example, options changes identity on every render, so it defeats the memoization:

const options = { matchMode: 'whole-word', text };
const results = useMemo(
  () => search(items, options),
  [items, options]
);

Prefer depending directly on the primitive inputs and creating the object inside the calculation:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const results = useMemo(() => {
  const options = { matchMode: 'whole-word', text };
  return search(items, options);
}, [items, text]);

If a stable object identity is genuinely needed outside that calculation, memoizing the object can be appropriate. Do not add another memoization layer reflexively; first identify which identity a consumer actually needs to remain stable.

When is useMemo worth using?

Use it selectively when there is a clear performance or identity problem, rather than wrapping every calculation. It is most likely to help in these cases:

  • A calculation is noticeably slow, its inputs change infrequently, and a component renders often for other reasons.
  • A calculated value is passed to a child wrapped in memo, and stable props allow that child to skip work.
  • A calculated value is used as a dependency of another Hook, such as useEffect, and stable identity prevents unnecessary reruns.

A typical example is filtering or transforming a large array while unrelated UI state changes. If the array or query changes, the calculation needs to run again; if only unrelated state changes, React can reuse the previous result.

Profile before optimizing

Measure the actual interaction in a production-mode build. The React DevTools Profiler can help identify which components render and how much work they do; CPU throttling can approximate performance on a slower device. Development timings can be misleading because Strict Mode may repeat work and a developer’s computer may be faster than the device being optimized.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compare the direct calculation with the memoized version under representative conditions. Consider the calculation’s cost, how often its dependencies change, how frequently the component renders, whether consumers need stable identity, and whether the measured production improvement outweighs added memory use and code complexity. A cheap calculation may be clearer and no slower when written directly.

Why might the calculation run twice?

In development Strict Mode, React may call the component and the useMemo calculation twice when dependencies change; it ignores one result. This helps expose impure calculations, such as code that mutates an existing array. A pure calculation returns a result without changing external state, so an extra development call does not change its outcome. This behavior is not a reason to add side effects or mutation to the calculation.

What useMemo does not guarantee

React’s guidance is explicit: “You should only rely on useMemo as a performance optimization.” The cached value is not a semantic guarantee. React may discard it in documented circumstances, including when a component suspends during its initial mount. If correctness depends on a value persisting, use the appropriate state or ref mechanism instead.

Hooks must be called at the top level—not conditionally or inside loops. If you omit the dependency array, the calculation runs on every render. If the callback performs side effects or does not return a value, useMemo is the wrong tool; use the Hook designed for that job, such as useEffect for synchronizing with external systems.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

useMemo, useCallback, and memo compared

These APIs address different parts of rendering. Their benefits depend on actual render behavior and stable identities, not merely on using the APIs together.

API What it stabilizes or skips Typical purpose
useMemo A calculated value Reuse an expensive result or provide a stable calculated value to a consumer.
useCallback A function Keep a function identity stable; often clearer than returning a function from useMemo.
memo A component render when its props are unchanged Let a component skip rendering when its parent renders but its props remain the same.

For instance, memo can help a child skip work only if its props stay unchanged. Passing a freshly created object or function each time can undermine that condition; useMemo or useCallback can stabilize a prop when profiling shows that doing so matters. See React’s useCallback reference and memo reference.

Does React Compiler replace useMemo?

React’s React Compiler documentation says the compiler can automatically memoize values and functions, reducing the need for many manual useMemo calls. Manual use remains available when explicit control is useful. Follow the compiler configuration for your project and verify its behavior in your own build; compiler availability and setup are project-specific.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.