« All posts

React useCallback vs useMemo: When Do You Really Need Them

Wrapping every function in useCallback can hurt performance instead of helping. Learn a profiler-first approach to knowing when useMemo and useCallback actually matter.

This piece tackles a common React anti-pattern: wrapping every function in useCallback and every array in useMemo out of habit rather than need. Using React Profiler measurements, the author shows that over-memoising actually degrades render performance, since dependency comparisons themselves carry a cost — and without a memoized child component (React.memo), these hooks accomplish nothing. A concrete case study on a 500-row admin table shows how memoizing every cell formatter worsened scroll jank, with the real fix being list virtualization rather than more hooks.

Technically, useMemo caches a computed value across renders while useCallback caches a function reference; neither prevents the parent itself from re-rendering — they only help a React.memo-wrapped child skip unnecessary work. The author labels memo hooks added without a memoized consumer as 'memo soup,' pure wasted code that provides no benefit.

The practical rule of thumb: default to no memo hooks at all, and add them only when the Profiler reveals an actual problem. Use useMemo for expensive derived values feeding memoized children, and useCallback for stable handlers passed to those same children. Blindly adding memo hooks just to silence ESLint's exhaustive-deps rule is flagged as the most common wasted code the author removes during review.

» SourceDev.to