Concepts/React

useMemo vs useCallback

useMemo memoizes a computed VALUE, useCallback memoizes a FUNCTION reference. Both use dependency arrays to control when recalculation happens.

Side-by-Side Comparison

FeatureuseMemouseCallback
What it memoizesA computed valueA function reference
ReturnsThe cached resultThe cached function
Primary use caseExpensive computationsStable callback references
Works with React.memoIndirectly (via stable values)Directly (stable function props)
EquivalentuseMemo(() => value, deps)useMemo(() => fn, deps)

Code Examples

useMemo

  • Memoizes the RETURN VALUE of a function
  • Recalculates only when dependencies change
  • Avoids expensive recomputation on every render
  • Returns the cached value, not a function
function ProductList({ items, filter }) {
  // Only recalculates when items or filter change
  const filtered = useMemo(
    () => items.filter(i => i.name.includes(filter)),
    [items, filter]
  )

  return filtered.map(item => <Item key={item.id} item={item} />)
}

useCallback

  • Memoizes the FUNCTION ITSELF (its reference)
  • Returns the same function reference between renders
  • Useful when passing callbacks to memoized children
  • useCallback(fn, deps) === useMemo(() => fn, deps)
function Parent({ id }) {
  // Same function reference unless id changes
  const handleClick = useCallback(
    () => { console.log('Clicked', id) },
    [id]
  )

  // Child won't re-render if wrapped in React.memo
  return <MemoizedChild onClick={handleClick} />
}

When to Use Which

useMemo

Expensive calculations (filtering/sorting large lists), deriving data from props/state, creating objects/arrays passed as props to memoized children.

useCallback

Callbacks passed to React.memo children, event handlers used in useEffect dependency arrays, functions passed to custom hooks.

Common Mistakes

Interview Questions

When is useMemo actually harmful?

When the computation is trivial (simple math, string concatenation). Memoization adds memory overhead and dependency comparison cost. Only use it when profiling shows the computation is expensive enough to justify caching.

Why is useCallback useless without React.memo?

Without React.memo, the child component re-renders whenever its parent re-renders regardless of prop changes. useCallback preserves function identity, but that only matters if something is actually checking for reference equality — which React.memo does.

How does the React Compiler change useMemo/useCallback?

React Compiler (React Forget) automatically memoizes values and callbacks, making manual useMemo/useCallback unnecessary. It analyzes your code at build time and inserts memoization where beneficial.

Deep Dive