All topics
Performanceintermediate

Avoiding Unnecessary Re-renders

Learn the common causes of unnecessary component re-renders and the standard techniques to prevent them.

An 'unnecessary' re-render is one where a component re-executes and reconciles even though its actual rendered output wouldn't change, wasting CPU time. The most common causes are: a parent re-rendering and passing new object/array/function literal props by reference every time, a Context value changing and re-rendering every consumer regardless of relevance, and state living higher in the tree than it needs to (not colocated).

It's like a manager who reflexively calls an all-hands meeting (a broad re-render) every time any single decision changes, versus one who only pulls in the specific people whose work is actually affected — the second approach gets the same outcome with far less wasted time from everyone who didn't need to be involved.

Key Concepts

1
The standard toolkit for addressing this includes React.memo (skip re-rendering a component if its props are shallowly equal), useMemo/useCallback (preserve referential stability of objects/arrays/functions passed as props, making React.memo actually effective), splitting large Context values into smaller, more targeted contexts, and colocating state closer to where it's actually used rather than lifting it prematurely.
React.memouseMemouseCallback
2
It's important to internalize that a re-render itself isn't inherently bad — React's diffing is generally fast, and only components whose actual DOM output changes result in real DOM mutations. The goal isn't zero re-renders, it's avoiding re-renders expensive enough to be noticeable, which is why profiling before optimizing (see the Profiler topic) matters: applying memoization broadly without evidence often adds complexity without measurable benefit.
3
Interviewers frequently present a component tree with a performance complaint and ask candidates to walk through likely causes methodically — checking for unstable prop references, overly broad context, and non-colocated state — rather than reaching immediately for React.memo everywhere as a reflexive first move.
React.memo