Note Prefer useReducer over useState when you have complex state logic with multiple sub-values, or when the next state depends on the previous state in varied ways. The reducer function must be pure -- no side effects.
import { useId } from'react';
function LabeledInput({ label, type = 'text' }) {
const id = useId();
return (
<div>
<label htmlFor={id}>{label}</label>
<input id={id} type={type} />
</div>
);
}
// Each instance gets a unique, stable ID
<LabeledInput label="Username" />
<LabeledInput label="Email"type="email" />
Note useId generates IDs that are stable across server and client renders, preventing hydration mismatches. Never use it for keys in a list. It is meant for accessibility attributes (htmlFor, aria-describedby, etc.).
useIdunique idaccessible labelhtmlFor idssr safe id
Note useDeferredValue lets the UI stay responsive by deferring re-rendering of expensive parts. It is similar to debouncing but integrated with React's rendering scheduler. Compare the deferred and current value to show a stale indicator.
useDeferredValuedefer renderresponsive inputdebounce renderingslow list filter
Note startTransition marks state updates as non-urgent, allowing urgent updates (like typing) to interrupt them. The isPending flag lets you show loading indicators. Unlike useDeferredValue, useTransition wraps the state update itself.
Note Designed for subscribing to external data sources (browser APIs, third-party stores) in a way that is compatible with concurrent rendering. The subscribe function must accept a callback and return an unsubscribe function.
useSyncExternalStoreexternal storesubscribebrowser api hookthird party state
Note useDebugValue only affects the React DevTools display for custom hooks. It adds no runtime behavior. Use the format function (second argument) to defer expensive string formatting until the hook is actually inspected in DevTools.