context
useId
Generates a unique, stable string ID that is consistent between server and client renders. Reach for it whenever you need to associate elements (label htmlFor, aria-describedby) without collisions in an SSR-safe way.
const id = useId() Parameters & Behavior
| Parameter | Purpose |
|---|---|
| return | A unique string like ':r0:' — stable across renders and hydration |
| prefix/suffix | Append your own suffix when one component needs multiple related ids |
| not for keys | Not intended for list keys — use data ids instead |
| SSR-safe | Same id emitted on server and client, so hydration doesn't mismatch |
Examples
const id = useId();
return (<><label htmlFor={id}>Name</label><input id={id} /></>); Associate a label with an input without hard-coding an id
const id = useId();
return (<><input aria-describedby={`${id}-help`} /><p id={`${id}-help`}>Enter your email</p></>); Suffix pattern for multiple related ids in one component
const id = useId();
return <svg><defs><linearGradient id={id}>...</linearGradient></defs><rect fill={`url(#${id})`} /></svg>; Unique SVG gradient id so multiple instances don't collide
const groupId = useId();
return <fieldset aria-labelledby={groupId}><legend id={groupId}>Options</legend>...</fieldset>; Accessible fieldset legend association
Gotcha
Do not use useId for list item keys — the id changes per component instance, not per data row. Never generate ids with Math.random inside components; hydration will mismatch.
Related hooks
useContext
Reads the current value of a React context from the nearest matching Provider above in the tree. Reach for it to share values like themes, auth, or locale without prop-drilling through every intermediate component.
useRef
Returns a mutable object whose .current property persists for the lifetime of the component without triggering re-renders on change. Reach for it to hold DOM nodes, timers, previous values, or any imperative handle that render output does not depend on.
useSyncExternalStore
Subscribes a component to an external store in a way that is safe with concurrent rendering, preventing tearing. Reach for it when writing a library or reading from a store that lives outside React (Redux, Zustand, browser APIs, custom event emitters).