Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Priority-based updates — startTransition से urgent और non-urgent rendering।
useTransition एक React 18 hook है जो आपको state updates को 'non-urgent transitions' के रूप में mark करने देता है। Urgent updates (typing, clicking) तुरंत process होते हैं और कभी interrupt नहीं होते। Transition updates lower-priority होते हैं — यदि transition in progress होने के दौरान कोई urgent update आता है, तो React transition को interrupt करता है, urgent काम handle करता है, फिर transition को restart करता है। यह heavy re-renders के दौरान भी UI को responsive रखता है।
React scheduler प्रत्येक update को एक priority lane assign करता है: SyncLane (urgent, unbatchable), InputContinuousLane (drag/scroll), DefaultLane (normal setState), और TransitionLane (useTransition / startTransition)। Higher-priority lanes हमेशा lower ones को preempt करते हैं।
startTransition(callback) में setState call को wrap करना React को बताता है: 'यह update एक transition है — इसे interrupt किया जा सकता है'। React इसे TransitionLane में schedule करता है और transition complete होने तक current UI visible रखता है।
यदि user एक और character type करता है जबकि transition के रूप में 5000-item list re-render हो रही है, तो React transition render को mid-tree pause करता है, typing (urgent) को immediately process करता है, input update करता है, फिर transition को नई input value के साथ scratch से restart करता है।
useTransition [isPending, startTransition] return करता है। isPending true होता है जब React transition process कर रहा होता है। UI को block किए बिना एक subtle loading indicator दिखाने के लिए इसका उपयोग करें।
startTransition का एक alternative: useDeferredValue(value), value की एक deferred copy return करता है जो transitions के दौरान पीछे रहती है। UI पहले पुराने deferred value के साथ render होता है (fast), फिर React के पास समय होने पर नई value के साथ re-render होता है।
Transition updates के लिए एक low-priority scheduler lane। किसी भी higher-priority काम (user input, sync updates) द्वारा preempt किया जा सकता है।
अपने callback के अंदर setState calls को non-urgent mark करता है। Standalone import के रूप में या useTransition hook से उपलब्ध।
useTransition से Boolean। True जब React अभी भी transition update process कर रहा हो। Input block किए बिना spinner दिखाने के लिए उपयोग करें।
एक value की deferred copy return करता है। पहले stale value के साथ render होता है (instant), idle होने पर fresh value के साथ re-render होता है। Large lists filter करने के लिए उपयोगी।
जब transition mid-way पर एक urgent update आता है, React in-progress transition render को discard करता है और urgent काम handle करने के बाद इसे fresh restart करता है।
1import { useState, useTransition } from 'react';23function SearchPage() {4 const [query, setQuery] = useState('');5 const [results, setResults] = useState(allItems);6 const [isPending, startTransition] = useTransition();78 function handleChange(e) {9 // Urgent: update the input immediately (never interrupted)10 setQuery(e.target.value);1112 // Non-urgent: filter 10,000 items as a transition13 startTransition(() => {14 setResults(allItems.filter(item =>15 item.name.includes(e.target.value)16 ));17 });18 }1920 return (21 <>22 <input value={query} onChange={handleChange} />23 {isPending && <Spinner />} {/* subtle loading indicator */}24 <ResultsList items={results} />25 </>26 );27}
Transitions से पहले, React सभी state updates को same priority पर render करता था — एक heavy list re-render, input को सैकड़ों milliseconds के लिए freeze कर सकती थी। Transitions आपको React को explicitly बताने देते हैं 'user को input instant लगना चाहिए, लेकिन results list एक moment ले सकती है'। यही अंतर है एक laggy app और एक smooth app में जब महंगे renders से deal करना हो।
A dashboard has tabs: Overview, Analytics, Reports. Clicking 'Analytics' loads heavy chart components. Without transitions, the current tab disappears immediately and the user sees a loading blank until the new tab renders.
The tab switch calls `setActiveTab('analytics')`, which immediately unmounts the Overview tab and starts rendering Analytics. The heavy chart render blocks the main thread for 300ms. During this time, the user sees a blank panel — the old tab is gone, the new tab isn't ready.
Wrap the tab switch in `startTransition(() => setActiveTab('analytics'))`. React keeps showing the Overview tab (marked with `isPending` for a subtle opacity/spinner indicator) while rendering Analytics in the background. When ready, it swaps them in a single frame — no blank state.
Takeaway: useTransition is perfect for tab switching, accordion expansions, and any UI where you want the old content to stay visible while new content prepares. The `isPending` boolean lets you show a subtle loading indicator without destroying the current view.
A search results component receives `query` as a prop and does heavy filtering inline. You want to defer the results rendering but can't wrap the parent's setState in startTransition because you don't control the parent.
The parent component calls `setQuery(e.target.value)` directly. You can't add startTransition because you don't own the parent component (maybe it's from a library). Your heavy ResultsList re-renders on every keystroke because `query` prop changes immediately.
Use `useDeferredValue(query)` in ResultsList: `const deferredQuery = useDeferredValue(query)`. Filter using `deferredQuery` instead of `query`. React returns the old value during heavy renders, showing stale-but-fast results while computing the new filter in the background. Compare `query !== deferredQuery` to show a loading indicator.
Takeaway: useDeferredValue is the consumer-side equivalent of useTransition. Use useTransition when you control the state update (can wrap setState). Use useDeferredValue when you want to defer derived rendering from a prop you don't control.