How Rendering Works in React
In this page:
What Triggers a Re-render
A component re-renders when its own state changes, when it receives new props from its parent, or when its parent re-renders for any reason (by default, regardless of whether that child's props actually changed).
Note: A parent re-rendering does not necessarily mean the real DOM changes -- React still diffs before touching the DOM.
Warning: Expecting a component to re-render just because some unrelated global variable changed is a common misunderstanding -- React only reacts to state/props changes it's aware of.
Example: What Triggers a Re-render
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Child() {
console.log('Child rendered');
return <p>I am the child.</p>;
}
function Parent() {
const [count, setCount] = React.useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Parent count: {count}</button>
<Child />
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Parent />);
</script>
</body>
</html>
Render Phase vs Commit Phase
React rendering happens in two phases: the render phase calculates what should change (calling your component functions), and the commit phase actually applies those changes to the real DOM.
Note: Your component function itself should stay free of direct DOM manipulation -- that belongs in the commit phase, which React manages, or in an effect afterward.
Warning: Directly mutating the DOM inside a component's function body (during the render phase) can cause inconsistent UI, since render can run more than once before anything commits.
Example: Render Phase vs Commit Phase
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function PhaseNote() {
const [n, setN] = React.useState(0);
return <button onClick={() => setN(n + 1)}>Render calculates, commit applies: {n}</button>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<PhaseNote />);
</script>
</body>
</html>
Batching Multiple State Updates
When several state updates happen inside the same event handler, React groups them into a single re-render instead of re-rendering once per update. This batching keeps the UI fast and consistent, since a component never shows a half-updated in-between state to the user.
Note: You can call multiple setState functions in a row inside one handler without worrying about extra renders -- React batches them automatically.
Warning: Because updates are batched, reading state right after calling its setter inside the same handler still gives you the OLD value, not the new one.
Example: Batching Multiple State Updates
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Toggler() {
const [a, setA] = React.useState(false);
const [b, setB] = React.useState(false);
function handleClick() {
setA(true);
setB(true);
}
return (
<div>
<button onClick={handleClick}>Set Both</button>
<p>A: {String(a)}, B: {String(b)}</p>
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Toggler />);
</script>
</body>
</html>
- Assuming every state update triggers an immediate, separate render -- React often batches multiple updates into one.
- Confusing the render phase (calculating what should change) with the commit phase (actually updating the DOM).
- Reading a state variable right after calling its setter and expecting the new value in the same function call.
- A re-render happens when a component's state or props change.
- React first calculates what changed (render phase) before touching the real DOM (commit phase).
- Multiple state updates inside the same event handler are batched into a single re-render.
- Understanding this cycle helps explain why state updates don't apply instantly mid-function.
No browser-specific restrictions -- an internal React rendering behavior available in every React version, with expanded automatic batching since React 18.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: