Part 7 · 2 chapters · ~12 min

React

From a state change to a committed DOM: the element tree, fibers, reconciliation and keys, lanes and concurrency, Server Components and the compiler; then hooks and state patterns.

16

How React renders

From a state change to a committed DOM: elements, fibers, reconciliation, scheduling and the server.

Virtual DOM

staterender()element treediffvs previousDOM patchminimal

A lightweight tree of elements describing what the UI should look like, compared against the previous tree to compute the DOM changes.

in practiceJSX compiles to createElement calls producing it; the reason React can batch and schedule DOM writes.

deep dive: React P0

Fiber

App fiberHeaderListItemItemchild / sibling / return pointers

React's internal unit of work: one node per component instance with links to child, sibling and return, so rendering can pause and resume.

in practiceThe React DevTools component tree; why rendering can be interrupted in concurrent mode.

deep dive: React P1

Reconciliation

same type, same keyupdate propskeep statedifferent type or keyunmount oldmount newstate lost

Comparing the new element tree with the current fiber tree to decide what to create, update, move or delete.

in practiceKeys deciding identity in lists; changing a component type remounting its whole subtree.

deep dive: React P2 · Algorithms P7

Keys

key={item.id}moves keep their statekey={index}reorder = wrong statekey={Math.random()}remount every render

Stable identities for list children so reconciliation can match items across renders instead of by position.

in practiceIndex keys scrambling input state when a list is reordered; key to reset a component on purpose.

deep dive: React P2

Render phase vs commit phase

renderpure, inter…commitDOM writes,…layout e…before painteffectsafter paint

Render computes what changed and can be interrupted or repeated; commit applies changes to the DOM and runs layout effects synchronously.

in practiceWhy render must be pure (it may run twice in StrictMode); why useLayoutEffect blocks paint.

deep dive: React P1

Lanes

SyncLanediscrete inputInputContinuousLanedrag, scrollDefaultLanefetch resultTransitionLanesstartTransitionIdleLaneoffscreen

React's bitmask priorities for updates (sync, input, default, transition, idle), letting urgent updates interrupt less urgent ones.

in practicestartTransition marking an update as interruptible; input staying responsive during a heavy list filter.

deep dive: React P3

Concurrent rendering

render (transit…input!render (resume)commit51 ms

Rendering that can be paused, resumed or thrown away, so React can keep the UI responsive and prepare new screens in the background.

in practiceuseTransition, useDeferredValue, Suspense with transitions.

deep dive: React P5

Batching

setA()setB()setC()one rend…

Grouping several state updates into one render; automatic in React 18+ for updates in the same tick, including in promises and timeouts.

in practiceThree setState calls in a handler causing one render, not three.

deep dive: React P4

Suspense

while pending<Spinner />fallback shownwhen ready<Comments />content revealed

A boundary that shows a fallback while something inside is not ready (code, data), then reveals the content.

in practiceRoute-level loading states; streaming SSR sending each boundary as it resolves.

deep dive: React P5 · React P8

Server Components

Server Componentruns on serverno JS shippedreads DB directlyClient Component"use client"ships JSstate, effects, events

Components that run only on the server, send serialised output (not code) to the client, and can read data directly.

in practiceNext.js App Router; "use client" boundaries; smaller bundles for read-only UI.

deep dive: React P6

React Compiler

component co…compileranalysememoised out…auto cache

A build-time compiler that memoises components and values automatically based on its analysis of the code.

in practiceRemoving hand-written useMemo and useCallback; requires code to follow the rules of React.

deep dive: React P6

StrictMode

mountunmount (dev)cleanupmount againdid it hold?

A development wrapper that double-invokes render and effects to surface impure renders and missing cleanups.

in practiceEffects firing twice in dev; a hint that cleanup is missing, not a bug in React.

deep dive: React P11
THE REACT LAYER, IN ORDER
from a state change to a committed DOM, and the hooks and patterns that sit on top
swipe the figure sideways, or tap expand for full screen
1/6
describe
Describe: components return element trees; React keeps fibers, one per instance, as the work units; StrictMode checks render is pure.
17

Hooks and state patterns

The hooks and the state patterns built on top of them.

useState

const [n, setN] = useState(0);setN(n + 1); setN(n + 1); // n + 1setN(p => p + 1); setN(p => p + 1); // n + 2

A hook that keeps a value across renders and schedules a re-render when set; updates are queued, not applied immediately.

in practiceReading state right after setting it returns the old value; functional updates for derived next values.

deep dive: React P4

useEffect

commitpainteffectsubscribecleanupnext run / …

Runs a side effect after commit and paint, re-running when dependencies change and cleaning up before the next run and on unmount.

in practiceSubscriptions, timers, imperative APIs; not for deriving state or fetching on every render.

deep dive: React P4

useLayoutEffect

commit DOMlayout effectmeasure, fixpaint

Like useEffect but runs synchronously after DOM mutation and before paint, so measurements and corrections are not visible.

in practiceMeasuring a tooltip before positioning it; blocks paint, so keep it short.

deep dive: React P4

useRef

useStatechange → re-rendervalue in renderuseRefchange → nothing.current any time

A mutable box that persists across renders without causing re-renders; also how React hands you DOM nodes.

in practiceDOM refs for focus; storing the latest callback or a timer id.

deep dive: React P4

useMemo and useCallback

const sorted = useMemo( () => rows.toSorted(byPrice), [rows]);const onPick = useCallback(id => pick(id), [pick]);

Cache a computed value or a function identity between renders until dependencies change.

in practiceStable props for memoised children; expensive derived data. Largely replaced by the React Compiler.

deep dive: React P4

Context

Provider valuePageuseCont…CardSidebaruseCont…every consumer re-renders on change

Passing a value to a subtree without props; every consumer re-renders when the value changes.

in practiceTheme, auth, locale; a large context value changing on every keystroke re-rendering the app.

deep dive: React P4 · React P7

Derived state

stored + synceduseState(total)useEffect → setTotalextra render, can driftderivedconst total = items.reduce(…)always correct

Values computed from props or state during render rather than stored and synced with effects.

in practiceThe "useEffect to set state from props" anti-pattern and its double render.

deep dive: React P7 · React P11

Lifting state up

Parent (owns value)InputAInputBone source of truth, passed down

Moving shared state to the nearest common parent so siblings read one source of truth.

in practiceTwo inputs that must agree; the step before reaching for a store.

deep dive: React P7

Server state

UI stateowned by clientmodal open, tabuseStateserver statecached copystale, refetchquery library

Data owned by the server and cached on the client: it can be stale, shared and refetched, unlike UI state.

in practiceTanStack Query, SWR, RTK Query; cache keys, stale times, invalidation after mutations.

Optimistic update

uiservershow likedPOST /like200 (keep) or 500 (roll back)

Showing the result of a mutation before the server confirms it, and rolling back if it fails.

in practiceLikes, reorders, todo toggles; useOptimistic in React 19. Not for money movement.

deep dive: React P8 · Trust P7

Controlled vs uncontrolled input

controlledvalue={state}onChange → setStatere-render per keyuncontrolleddefaultValueDOM holds valueread on submit

Controlled inputs keep their value in React state; uncontrolled ones keep it in the DOM and are read on submit.

in practiceTyping lag in big controlled forms; form actions and FormData favouring uncontrolled.

deep dive: React P9

Error boundary

AppErrorBoundaryChart (…fallbackNav

A component that catches render errors in its subtree and shows a fallback instead of unmounting the whole app.

in practicePer-widget fallbacks on dashboards; does not catch event handler or async errors.

deep dive: React P10