React Rendering Mental Model
The most common gap in senior React interviews isn't knowledge of APIs â it's a missing mental model for how rendering actually works.
The Render Cycle
React rendering has three phases:
- Trigger â state change, prop change, or parent re-render
- Render â React calls your component function to compute the new virtual DOM
- Commit â React applies the minimal set of DOM mutations
The key insight: rendering â DOM updates. React can render a component and decide nothing needs to change in the DOM.
When Does a Component Re-render?
A component re-renders when:
- Its state changes (via
useState,useReducer) - Its parent re-renders (regardless of whether props changed)
- A context it consumes changes
A component does NOT re-render when:
- Its props change but its parent doesn't re-render (props can't change without a parent re-render)
- A sibling re-renders
The Props Misconception
This is where most mid-level engineers get it wrong:
"Components re-render when their props change"
This is false. Components re-render when their parent re-renders. Props changing is a consequence of the parent re-rendering, not the cause of the child re-rendering.
This distinction matters for optimization. React.memo() makes the "props changed" check actually matter â without it, the component re-renders regardless.
Optimization Hierarchy
From most to least impactful:
- Move state down â keep state close to where it's used
- Lift content up â pass JSX as children to avoid re-rendering static subtrees
React.memoâ skip re-render if props haven't changeduseMemo/useCallbackâ stabilize values and references- Virtualization â for long lists, don't render what's not visible
// Anti-pattern: state too high
function App() {
const [search, setSearch] = useState('');
return (
<div>
<SearchInput value={search} onChange={setSearch} />
<ExpensiveTree /> {/* Re-renders on every keystroke */}
</div>
);
}
// Fix: move state down
function App() {
return (
<div>
<SearchSection /> {/* Contains its own state */}
<ExpensiveTree /> {/* Never re-renders unnecessarily */}
</div>
);
}Architect Thinking
In a large application, rendering performance is an architectural concern, not a component-level optimization. Design your state topology so that expensive re-renders are structurally impossible, rather than relying on memo everywhere.
The best optimization is the one you never have to write.