Automatic batching or startTransition for safe rollback of a schema-driven UI state change in React 18
0 reputation · 08 Feb 2020, 15:57 UTC
0 reputation · 08 Feb 2020, 15:57 UTC
I have a React 18 app (concurrent renderer) where a single user action applies a "schema change" to local UI state: several components update their shape at once, driven by multiple setState calls, and a companion async fetch validates the new schema. If that fetch rejects, I want the UI to return to the previous consistent state rather than showing a half-migrated tree.
With automatic batching, all the updates commit in one render, which keeps the UI consistent, but I lose any intermediate loading state and I cannot tell whether the commit happened before or after the validation fetch settled. With startTransition, the update is interruptible and I can keep the old UI visible via isPending, but the scheduler decides when to yield, and if the async validation fails mid-transition there is no documented mechanism that guarantees the partially rendered work is discarded rather than committed.
Error boundaries only catch render-phase errors, and rejected promises inside a transition callback appear to bypass them, so the rollback path would have to be manual state restoration in a catch.
33775 reputation · 08 Feb 2020, 23:42 UTC
For a multi-component schema-driven state migration that must commit all-or-nothing, automatic batching is the documented safer choice. React 18 batches multiple setState calls from a single event handler into one render, so the UI never exposes a half-migrated tree. startTransition marks updates as non-urgent and interruptible, but React does not provide a public API to abort a pending transition from outside, nor does it guarantee that interrupted work is discarded rather than committed.
Neither batching nor startTransition gives transactional rollback. The supported safe pattern is:
setState calls..catch handler.There is no supported way to abort a pending startTransition from outside so the old committed tree stays on screen after a validation failure. The isPending flag only signals that a transition has not yet committed; it does not order the commit relative to your validation fetch settling. If you need the old UI to remain visible, capture a state snapshot before the migration and restore it in the fetch rejection handler.
Core batching and startTransition semantics are unchanged between React 18.2 and 18.3. Lane-priority behavior has minor internal differences that are not contractual; do not rely on yield timing or commit ordering. The recommended approach and rollback pattern apply to both minor versions, but verify your installed react and react-dom versions against the official React 18 changelog.
Diagnostic detail: If you can share the exact React minor version and whether the migration is gated by a single status variable (e.g., status: 'migrating'), I can confirm whether a single-setState gating approach eliminates the need for manual snapshot restoration.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.