Why does a component re-render?
Solution and explanation
The triggers
A component re-renders when:
- **Its state changes** (
setStatewith a different value). - **Its parent re-renders** (by default every child re-renders too, even with the same props).
- **A context it consumes changes value.**
- **A custom hook it uses** changes its internal state.
Props changing is not a separate trigger: props only change because the parent re-rendered.
Re-rendering means "React calls the function again and diffs the result". It does not necessarily change the DOM. Re-renders are usually cheap; they become a problem only when a large tree or expensive calculation re-runs often.
Example
function Page() {
const [query, setQuery] = useState('');
return (
<>
<input value={query} onChange={e => setQuery(e.target.value)} />
<ExpensiveChart data={chartData} /> {/* re-renders on every keystroke */}
</>
);
}
Fixes
- **Move state down:** put
queryand the input in their own<SearchBox>soPagedoes not re-render. - **Pass content as children:** components given as
childrenfrom above are not re-created by the state owner. - **
React.memo** onExpensiveChart, with stable props (useMemo/useCallback). - **Split contexts** or use selector-based stores so consumers only re-render for the slice they use.
- **
useDeferredValue/startTransition** to keep typing responsive while a heavy list updates.
Finding unnecessary re-renders
- React DevTools Profiler: "Highlight updates when components render" and "Why did this render?".
console.count('JobRow render')during development.
Summary
State changes, parent renders and context changes cause re-renders; keep state close to where it is used, and memoise only where profiling shows real cost.
