All topics
Hooksintermediate

useId for Accessible Unique IDs

Learn how useId generates stable, unique identifiers for accessibility attributes without mismatching between server and client.

useId() returns a unique string identifier that's stable across a component instance's lifetime, intended primarily for linking form elements to their labels and ARIA attributes (htmlFor, aria-describedby, aria-labelledby). It was added in React 18 specifically to solve an SSR-hydration problem that ad-hoc ID generation approaches ran into.

useId is like assigning permanent seat numbers printed on tickets before the show even starts, rather than having ushers hand out numbers as people walk in — everyone (server and client) agrees on the same seat assignment in advance, so there's no mismatch when people take their seats.

Key Concepts

1
Before useId, developers often generated IDs with an incrementing counter or Math.random(). That approach breaks under server-side rendering because the server and client can produce different ID sequences (especially with concurrent rendering, or multiple roots on a page), causing a hydration mismatch warning and potentially incorrect ARIA associations after hydration.
useIdMath.random()
2
useId guarantees the same ID is generated on the server and the client for the same component tree position, avoiding that mismatch entirely, and it deliberately produces IDs that are unique across the whole page (even across multiple independent React roots) using a structured format rather than a simple counter.
useId
3
Interviewers ask about useId mostly in the context of accessibility and SSR — a good answer connects it to hydration correctness, not just 'it makes a random string,' and clarifies it's not meant for keys in a list (which should be derived from data, not generated).
useId