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 se urgent aur non-urgent rendering.
useTransition ek React 18 hook hai jo aapko state updates ko 'non-urgent transitions' mark karne deta hai. Urgent updates (typing, clicking) turant process hote hain aur kabhi interrupt nahi hote. Transition updates lower-priority hote hain â agar transition in progress hote waqt koi urgent update aata hai, toh React transition interrupt karta hai, urgent kaam handle karta hai, phir transition restart karta hai. Yeh UI ko responsive rakhta hai chahe heavy re-renders ho rahe hon.
React scheduler har update ko ek priority lane assign karta hai: SyncLane (urgent, unbatchable), InputContinuousLane (drag/scroll), DefaultLane (normal setState), aur TransitionLane (useTransition / startTransition). Higher-priority lanes hamesha lower wale ko preempt karte hain.
startTransition(callback) mein ek setState call wrap karna React ko batata hai: 'yeh update ek transition hai â ise interrupt kiya ja sakta hai'. React ise ek TransitionLane mein schedule karta hai aur current UI tab tak visible rakhta hai jab tak transition complete nahi ho jaata.
Agar user ek aur character type karta hai jab ek 5000-item list transition ki tarah re-render ho rahi hai, toh React transition render ko tree ke beech mein pause karta hai, typing (urgent) turant process karta hai, input update karta hai, phir naye input value ke saath transition scratch se restart karta hai.
useTransition [isPending, startTransition] return karta hai. isPending tab true hota hai jab React transition process kar raha hota hai. UI block kiye bina ek subtle loading indicator dikhane ke liye ise use karo.
startTransition ka ek alternative: useDeferredValue(value) value ki ek deferred copy return karta hai jo transitions ke dauran peechhe reh jaati hai. UI pehle purane deferred value ke saath render hoti hai (fast), phir jab React ke paas waqt hota hai tab nayi value ke saath re-render hoti hai.
Transition updates ke liye ek low-priority scheduler lane. Kisi bhi higher-priority kaam (user input, sync updates) se preempt ho sakta hai.
Iske callback ke andar setState calls ko non-urgent mark karta hai. Standalone import ki tarah ya useTransition hook se available hai.
useTransition se boolean. Tab tak true rehta hai jab tak React transition update process kar raha hota hai. Input block kiye bina spinner dikhane ke liye use karo.
Ek value ki deferred copy return karta hai. Pehle stale value ke saath render karta hai (instant), idle hone par fresh value ke saath re-render karta hai. Bade lists filter karne ke liye useful.
Jab transition ke beech mein ek urgent update aata hai, React in-progress transition render discard karta hai aur urgent kaam handle karne ke baad ise fresh se restart karta hai.
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 se pehle, React saare state updates ek hi priority par render karta tha â ek heavy list re-render input ko saikdon milliseconds ke liye freeze kar sakta tha. Transitions aapko explicitly React ko batane dete hain ki 'user ko input instant feel karna chahiye, lekin results list thoda waqt le sakti hai'. Yeh expensive renders ke saath laggy app aur smooth app ka fark hai.
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.