useId, useTransition & useDeferredValue
📖 Concept
React 18 introduced several hooks to handle concurrency and accessibility.
1. useId: Generates unique IDs that are stable across the server and client. Essential for accessibility (linking labels to inputs) in SSR/Next.js apps.
2. useTransition:
Allows you to mark state updates as "non-urgent". This keeps the UI responsive while a heavy update is happening in the background. It provides a isPending flag to show a loading state.
3. useDeferredValue:
Similar to useTransition, but used when you receive a value from props and want to "defer" re-rendering the heavy parts of the UI that depend on that value.
💻 Code Example
1import { useState, useTransition, useDeferredValue, useId } from 'react';23function SearchResults({ query }) {4 // 1. Defer the heavy list rendering5 const deferredQuery = useDeferredValue(query);67 // Imagine this is a heavy calculation based on deferredQuery8 const items = Array.from({ length: 5000 }, (_, i) => `Result ${i} for ${deferredQuery}`);910 return (11 <ul className="opacity-50 transition-opacity duration-500" style={{ opacity: query !== deferredQuery ? 0.5 : 1 }}>12 {items.map(item => <li key={item}>{item}</li>)}13 </ul>14 );15}1617function App() {18 const [query, setQuery] = useState('');19 const [isPending, startTransition] = useTransition();20 const id = useId(); // 2. Stable ID for accessibility2122 const handleChange = (e) => {23 // 3. Keep the input feeling snappy!24 const value = e.target.value;25 setQuery(value);26 };2728 return (29 <div className="p-10">30 <label htmlFor={id}>Search:</label>31 <input32 id={id}33 value={query}34 onChange={handleChange}35 className="border p-2 ml-2"36 />3738 {isPending && <p>Loading new results...</p>}3940 <SearchResults query={query} />41 </div>42 );43}
🏋️ Practice Exercise
- Implement
useIdin a reusable 'Input' component to link the label and input correctly. - Build a large list filter and use
useTransitionto show a 'pending' state while the list updates. - Compare
useDeferredValuewith a traditionaldebouncefunction. - Research why
useIdis better thanMath.random()for generating IDs in React.
⚠️ Common Mistakes
Using
useTransitionfor small, fast updates where it just adds unnecessary complexity.Thinking
useDeferredValueworks like a debounce (it's actually more intelligent; it only defers if the CPU is busy).Using
useIdas a 'key' in a list (keys should come from your data, not be generated by hooks).
💼 Interview Questions
🎤 Mock Interview
Practice a live interview for useId, useTransition & useDeferredValue