Render, then commit
React chapter 137 · How React updates the screen · trigger → render → commit · source: react.dev/learn/render-and-commit
The problem
You push a new todo into the array and call setTodos(todos). The array grew, but the screen does not change. React compared the old and new value, saw the same array, and skipped the update.
The pattern that fixes it
Give React a new value: setTodos([...todos, item]). A different reference triggers a render, React diffs the new tree against the old one, and the commit touches only the one <li> that changed.
In plain words
React does not watch your variables. You tell it “here is the new state”, it runs your components again to see what the screen should be, then changes only the parts of the page that differ.
An architect redraws the whole plan on paper (render), but the builder only moves the walls that changed on the drawing (commit).
Terms
- trigger
- Something asks for an update: setState, new props from a parent, a context or store change.
- render
- React calls your component functions to get the next UI tree. No DOM is touched yet.
- commit
- React applies the difference between the old and new tree to the real DOM.
Going deeper
Why mutation is invisible
setState(next) bails out when Object.is(prev, next) is true. push changes the array in place, so prev and next are the very same object. Nothing is scheduled. The same rule powers memo, useMemo deps and selector equality later in the course.
Render is cheap-ish, commit is precise
A render can run many components and still produce zero DOM writes if the output is identical. That is why “avoid re-renders” is a performance tactic, not a correctness rule. Measure renders with the Profiler; measure DOM writes with the Performance panel.
Concurrent rendering
Since React 18 the render phase can be paused, thrown away or restarted (transitions, Suspense). The commit phase never is: it runs synchronously in one go. So render must be pure — no subscriptions, no DOM writes — and side effects belong in effects or event handlers.
Keep learning
- Previous: Pause RAF offscreen
- Next: State is a snapshot
- Related: State is a snapshot
- Related: Effects: sync, then clean up
- Related: Identity: position, type, key
- Related: Lift state up
- Related: useRef: remember without re-rendering
More courses
- Jobs, linked to lessons — Browse jobs where every requirement links to the chapter that teaches it. See how ready you are, how long the gap takes to close, and which listings look stale.
- Match a job post to courses — Paste a job post. Each skill is matched to a track here and put in learning order, foundations first.
- Database in depth — How a query becomes work. Indexes, isolation, locks, and the plans that explain why a page is slow — not an ORM tour.
- System Design — Eight interview case studies, from a flash sale and Tatkal to a live final and a chat model, plus JWT in separate chapters.
- Microservices — Microservice patterns one diagram at a time: how to split a monolith, how services talk, and how data stays consistent without distributed transactions.
- Kafka — A beginner-to-senior path through event logs, reliable delivery, production operations, and disaster recovery.
- Frontend system design — How a UI is sliced when it is a product, not a page: ownership of state, cache, routes, and what happens when the network lies.
- CSS in depth — See the box, then the page. Visual chapters from the box model through Flexbox surprises, Grid, selectors, and units, then backgrounds, shapes, and visual effects, each with a playground.
- Accessibility — HTML labs first, then a full pass of WAI-ARIA 1.3: naming, every state, widget and structure roles, live regions, ariaNotify, and relationships.
- Docker — What an image is, why layers cache, and how containers find each other on a network.
- Redis — Fifteen Redis patterns, one picture each: cache, session, lock, counter, rate limiter, queue, and when Redis is the wrong tool.