useMemo caches the result of an expensive calculation between renders, recomputing only when dependencies change. Use it after profiling — not by default on every value.
Caching Computed Values
const value = useMemo(() => compute(a, b), [a, b]) runs compute only when a or b change. Otherwise React returns the cached result from the previous render.
Memoization trades memory for CPU. Unnecessary useMemo adds complexity without measurable benefit. Profile first with React DevTools Profiler.
First argument is a function returning the value to cache.
Second argument is the dependency array.
Returns cached value when deps unchanged.
Not a semantic guarantee in concurrent React — treat as optimization hint.
useMemo vs useCallback vs React.memo
Three related but distinct optimization tools.
API
Caches
useMemo
Computed value result
useCallback
Function reference
React.memo
Component render output
Dependency array
Controls when cache invalidates
When to skip
Cheap computations, premature optimization
When NOT to useMemo
Primitive calculations, simple string concatenation, and small array filters rarely benefit. Memoization has its own overhead — measuring is essential.
Don't memoize everything by default.
Derive simple values inline during render.
Fix slow renders by restructuring before memoizing.
Use Profiler to identify actual bottlenecks.
Referential Equality for Dependencies
Child components wrapped in React.memo re-render when props change by reference. useMemo for objects/arrays passed as props prevents false-positive re-renders.