React Rendering Mental Model
React Rendering Mental Model
Understanding exactly when and why React re-renders a component is arguably the most important technical skill for a senior React developer. This is a very common topic in technical interviews.
The Standard Mental Model
Many beginners have an incorrect mental model of React rendering. They believe that a component re-renders when its props change.
This is completely false.
The correct mental model is this:
A React component re-renders if, and only if, its state changes, OR its parent component re-renders.
Props have absolutely nothing to do with whether a standard component re-renders. If a Parent component re-renders, all of its Children will automatically re-render, even if the props passed to those Children are completely identical to the previous render.
The Three Phases of a Render
To truly understand rendering, you must understand React’s internal process, which is divided into three distinct phases:
1. Trigger Phase
A render is added to the queue because of one of two things:
- It is the initial render of the application (using
createRoot().render()). - A component’s state has been updated (e.g., calling the
setfunction fromuseState).
2. Render Phase (Calling the Functions)
“Rendering” is just React calling your component functions.
When a state update triggers a render in a component (let’s call it <Parent>), React calls the Parent() function.
If the Parent() function returns a <Child /> component, React will then call the Child() function. It will continue doing this recursively down the entire tree until it hits the bottom.
This is why a child re-renders when a parent re-renders! React is just calling the functions recursively.
During this phase, React builds a new Virtual DOM and compares it to the old Virtual DOM (a process called Reconciliation or “diffing”).
3. Commit Phase (Mutating the DOM)
If, and only if, React finds a difference between the new Virtual DOM and the old Virtual DOM, it will “commit” those specific changes to the physical browser DOM using react-dom.
The Optimization Exception (React.memo)
The recursive rendering behavior (a Parent rendering forces all Children to render) is the default behavior because calling JavaScript functions is incredibly fast. React can usually call thousands of component functions in milliseconds.
However, if a Child component is extremely expensive to render (e.g., a massive data table), you don’t want it to re-render just because its Parent’s state changed.
This is where React.memo comes in.
If you wrap a component in React.memo, you change the default rule. You tell React: “If my Parent re-renders, check my Props first. If my Props have not changed, SKIP calling my function and just reuse my last render.”
// This component will ONLY re-render if 'data' or 'title' changes,
// even if its Parent re-renders.
const ExpensiveTable = React.memo(function ExpensiveTable({ data, title }) {
// ... heavy rendering logic ...
});
Interview Questions
Q: What is the fundamental React rendering mental model?
A: UI is a pure function of State: UI = f(State). Whenever the state changes, you should mentally picture React completely destroying the old UI and redrawing the entirely new UI from scratch based on the new state.