When does React re-render?
Overview
Before optimizing performance, you must understand when React naturally updates the screen. A component re-renders if and only if one of three things happens: 1. Its State changes (via useState or useReducer). 2. Its Props change (because the parent passed new data). 3. Its Parent re-renders. That last point is critical: by default, if a parent re-renders, ALL of its children will re-render recursively, even if their props didn't change at all!
Syntax
React's default behavior is to re-render the entire subtree. Usually, this is so incredibly fast (thanks to the Virtual DOM) that you don't even notice. But for massive components (like a heavy data grid), this cascade causes lag.
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>
Clicks: {count}
</button>
{/*
Even though <StaticChild> takes NO props, it will re-render
every single time the button is clicked!
*/}
<StaticChild />
</div>
);
}Common Pitfalls
- Assuming a child only re-renders when its props change. This is a very common misconception. Without memoization, children ALWAYS re-render when the parent renders.
Interview Tips
- If asked how to stop the 'Cascade Effect', the answer is `React.memo`.
Real-World Example
Using the React DevTools Profiler to record a session and see visually which components are rendering and exactly how many milliseconds they take.
import { Profiler } from 'react';
function onRenderCallback(
id, // the "id" prop of the Profiler tree that has just committed
phase, // either "mount" (if the tree just mounted) or "update" (if it re-rendered)
actualDuration, // time spent rendering the committed update
) {
console.log(`${id} took ${actualDuration}ms to ${phase}`);
}
function App() {
return (
<Profiler id="Dashboard" onRender={onRenderCallback}>
<Dashboard />
</Profiler>
);
}