Skip to content

dev48v/concurrent-lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚛️ Concurrent Lab — useTransition & useDeferredValue

Feel React's concurrent rendering. Type into a filter over a deliberately heavy list: in blocking mode the input janks while the big render runs; useDeferredValue and useTransition keep typing instant and update the list at a lower priority. Same list, same filter — different scheduling.

▶ Live demo  ·  The difference  ·  Run locally

License: MIT React 19 Vite TypeScript


Why

"Concurrent rendering keeps the UI responsive" is hard to appreciate until you feel a laggy input become smooth. This filters a genuinely heavy list (~1,200 costly rows) so blocking mode really does jank — and a live main-thread heartbeat freezes to prove it — then the concurrent hooks make it buttery.

What you can do

Three modes over the identical filter + list:

  • blocking (useState) — the filter runs synchronously on every keystroke. Rendering the heavy rows blocks the main thread, so the input itself stutters and the heartbeat dot freezes (watch the "worst frame gap" climb).
  • useDeferredValue — the input binds to the live value (instant); the list reads a deferred copy that lags at lower priority. While it catches up, the old list is shown dimmed.
  • useTransition — the keystroke updates the input immediately, and the filter update is wrapped in startTransition, so React renders the list at low priority and gives you an isPending flag. The input never blocks.

The difference

// useDeferredValue — defer a VALUE you already have
const deferred = useDeferredValue(text);
const list = useMemo(() => filter(deferred), [deferred]);

// useTransition — wrap the STATE UPDATE that causes the heavy work
const [isPending, startTransition] = useTransition();
onChange = (v) => { setText(v); startTransition(() => setQuery(v)); };

Both tell React "this update is low-priority — keep the UI interactive and finish it when you can." Use useDeferredValue when you already have the value (e.g. a prop); use useTransition when you own the state update and want an isPending flag for a spinner.

Run it locally

npm install
npm run dev
npm run build

Contributing

Ideas: a startTransition for route/tab switches, useDeferredValue with <Suspense>, an "interrupted render" visualization, comparison vs debouncing. PRs welcome.

If this made concurrent React click, a ⭐ helps others find it.

License

MIT © dev48v

About

Feel React concurrent rendering: blocking useState janks a heavy-list filter, while useDeferredValue and useTransition keep the input responsive. Live heartbeat, zero deps.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors