Understanding Rendering
At its core, React is a library for building UIs from a deceptively simple idea: your view is a pure function of your state. Yet one part of that idea confuses even experienced developers: when does React actually render?
- •What “rendering” really means in React
- •Exactly when React renders and re-renders components
- •How snapshots of props, state, and handlers work
- •When React skips a re-render
- •How batched state updates are calculated
- •Why children re-render and how memoization helps
You can condense React's mental model into a single equation:
v = f(s)Your UI (v) is the result of calling a function (f) with your component state (s). But that raises an important question: when exactly does React call f?
What Rendering Actually Means
Rendering is the process where React calls your component function to produce a description of the UI.
- •React takes a snapshot of your component at a point in time
- •That snapshot includes props, state, event handlers, and JSX
- •React uses the JSX output to update the actual DOM
import { createRoot } from "react-dom/client"
import Dashboard from "./Dashboard"
const el = document.getElementById("root")
const root = createRoot(el)
root.render(<Dashboard />)When Does React Re-render?
React only re-renders a component when its state changes.
If a parent component's state changes, React re-renders the parent — and then, by default, all of its children.
function Spark() {
console.log("Spark rendered")
return <span>✨</span>
}
export default function Header() {
const [count, setCount] = React.useState(0)
return (
<h1>
Greetings <Spark />{" "}
<button onClick={() => setCount(c => c + 1)}>Update</button>
</h1>
)
}Snapshots and Event Handlers
When an event handler runs, it sees the props and state from the snapshot of the render in which it was created.
export default function Lamp() {
const [mode, setMode] = React.useState("off")
function toggle() {
setMode("on")
console.log("Current mode inside handler:", mode)
}
return <button onClick={toggle}>{mode}</button>
}On the first click, the snapshot says mode = "off", so the console logs "off" even though you call setMode("on"). On the next render, the snapshot is updated.
When React Skips a Re-render
If you update state to the exact same value as before, React skips the re-render for that component.
export default function Counter() {
const [n, setN] = React.useState(5)
function reset() {
setN(5) // same as existing state
}
return <button onClick={reset}>{n}</button>
}How React Batches State Updates
Inside a single event handler, React batches state updates and applies them together after the handler finishes.
function handle() {
setLevel(10)
setLevel(20)
setLevel(30)
}The final value will be 30, not 10 → 20 → 30. With functional updates, each update can see the latest intermediate value:
function handle() {
setLevel(1) // Intermediate: 1
setLevel(l => l + 4) // Intermediate: 5
setLevel(100) // Overwrites: 100
setLevel(l => l + 6) // Final: 106
}StrictMode and Double Rendering
In development, React's StrictMode intentionally renders components twice to help surface impure logic and unsafe side effects.
import { StrictMode } from "react"
root.render(
<StrictMode>
<Dashboard />
</StrictMode>
)This behavior happens only in development and disappears in production builds.
Summary
- •React re-renders when state changes
- •Event handlers always see the snapshot from the render in which they were defined
- •React batches state updates and applies them together
- •Parents re-render → children re-render, unless you use memoization
- •StrictMode double-renders only in development
With this mental model, most React rendering questions become predictable — even in large applications.