useMemo
useMemo caches the result of an expensive computation between re-renders. It takes a factory function and a dependency array, returning the memoized value. It only recomputes when dependencies change.
useMemo is a recipe card with a Post-it: 'Same ingredients? Serve the leftovers. New ingredients? Cook again.'
useMemo is a performance optimization, not a semantic guarantee — React may throw away cached values under memory pressure. Common use cases: filtering/sorting large lists, computing derived data, creating objects/arrays passed as props to memoized children. Without useMemo, a new object reference on every render would defeat React.memo on child components. The factory runs during render, so it must be pure — no side effects.
In the React compiler (React Compiler), memoization is applied automatically, making manual useMemo largely unnecessary. The compiler analyzes data flow and inserts memoization at the optimal granularity. Until adoption is widespread, manual useMemo remains important. Profile before memoizing — useMemo itself has overhead (dependency comparison, closure creation, cache storage). For truly expensive computations, consider moving the work to a Web Worker instead of memoizing on the main thread.
useMemo caches expensive computations between renders, recomputing only when dependencies change. I use it for derived data from large lists, or to stabilize object references passed to memoized children. I always profile first because useMemo has its own cost — the React compiler will eventually automate this.
useMemo is not a guarantee — React can evict the cache. Don't rely on it for correctness (e.g., to prevent an effect from running). Also, memoizing cheap operations adds overhead for no benefit.