Concurrent Rendering, Suspense and Errors
Concurrent React can start, pause, abandon and repeat renders, so render must be pure. Suspense, transitions and deferred values decide when React shows a fallback and when it keeps the old UI. Error boundaries decide what happens when something fails.
Key points
- 1
Only Suspense-enabled sources suspend:
lazy(),use(promise)with a stable (cached) promise, and Suspense-enabled frameworks. Data fetched inuseEffectnever triggers a fallback. - 2
An urgent update that suspends inside an already-visible boundary shows the fallback and hides (not unmounts) the old children. The same update inside
startTransitionkeeps the old UI on screen instead. - 3
During a transition React still shows fallbacks for boundaries that are new, including boundaries remounted by a changed
key. Design navigations so the new layout contains its own boundaries. - 4
useTransitiongivesisPending. StandalonestartTransitiondoes not. In React 19 an async action keepsisPendingtrue until it settles, but state set after anawaitis not part of the transition unless you wrap it again. - 5
useDeferredValue(value, initialValue)renders the old value first and the new one in the background. It shows stale content instead of a fallback, and only saves work if the slow child is wrapped inmemo. - 6
React 19 commits a Suspense fallback as soon as one child suspends, then pre-renders the suspended siblings so their requests start in parallel. Nested boundaries reveal from the outside in, and reveals are throttled.
- 7
Error boundaries are class components that catch errors in render, lifecycles and effects below them, plus errors thrown by transition actions. They do not catch event handler, timer or their own errors. Reset them with a new
key.
Common traps
Calling
lazy()inside a component creates a new type every render, which remounts the subtree and re-suspends it.Caching a rejected promise means every retry after resetting the error boundary rethrows the same error. Evict the entry before retrying.
A hydration mismatch inside a Suspense boundary client-renders only that boundary; outside any boundary, React regenerates the whole root.
Read the source
Test yourself on Concurrent Rendering, Suspense and Errors
Ten questions, with the answer and explanation after each one.