useTransition: Deferred Concurrent Updates & Pending State Flags
- Last updated
- Prerequisites:
- SolidJS createResource
- SolidJS Suspense
- solidjs
- useTransition
- transitions
- suspense
- async
- concurrency
Read at your depth
The practical view
`useTransition` allows you to defer coordinate state updates that trigger `<Suspense>` boundaries. `const [pending, start] = useTransition();`. When you wrap a state change in `start(() => setTab('photos'))`, Solid keeps the current view on screen instead of falling back to the `<Suspense>` loading spinner, while setting `pending()` to `true` so you can show an inline progress bar.
The same idea in other frameworks
React `useTransition` / `startTransition` with concurrent lane preemption.Router navigation with loading indicators and resolvers.Vue Router navigation guards holding route component rendering.SvelteKit shallow routing and `navigating` store flags.Legacy vs modern
Immediate Suspense Fallback Flash vs useTransition Graceful Hold
Switching tabs without transition flashes an ugly full-page spinner; `useTransition` keeps the current tab visible until the new tab is ready.
setTab('heavyTab'); // ❌ Unmounts current tab and flashes Suspense fallbackstart(() => setTab('heavyTab')); // ✅ NEW: Holds current tab visible until readyInterview gotchas
Context
Interviewers test deep architectural comprehension across competing framework paradigms.
The mechanical answer
React implements `useTransition` via **CPU Time-Slicing across Virtual DOM Fibers**: it splits component tree rendering into interruptible 5ms chunks across priority Lanes. SolidJS has no Virtual DOM and renders synchronously; it implements `useTransition` as an **Asynchronous Suspense Coordinator**: it tracks pending `createResource` promises and delays swapping Suspense branches in the real DOM until all background fetches complete.
Trap
Do not say that SolidJS time-slices JavaScript execution on the main thread. Solid does not time-slice; it coordinates asynchronous resource boundaries.
Context
Checks knowledge of transition scope and resource requirements.
The mechanical answer
No. If a state update inside `start(() => ...)` does not trigger a pending `createResource` or async Suspense boundary, the update applies immediately and synchronously. `useTransition` only delays UI presentation when asynchronous resources suspend downstream.
Trap
Wrapping synchronous state changes (like toggling a boolean that renders a local static component) in `useTransition` will have no deferred effect.