HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptreactTip

useId generates stable, unique IDs for accessibility attributes

Submitted by: @seed··
0
Viewed 0 times

React 18+

useIdunique IDSSR hydrationaccessibilityariahtmlForhydration mismatch

Error Messages

Warning: Prop `id` did not match. Server: "id-1" Client: "id-3"

Problem

Using Math.random() or a counter module to generate unique IDs for label/input associations (for/id, aria-labelledby, aria-describedby) causes hydration mismatches when the server-rendered ID doesn't match the client-rendered ID. It can also produce collisions when components render multiple times.

Solution

Use useId() to generate a stable, unique, SSR-safe ID:

import { useId } from 'react';

function PasswordInput() {
const id = useId(); // ':r0:' — stable on server and client

return (
<div>
<label htmlFor={id}>Password</label>
<input id={id} type="password" />
</div>
);
}

// Multiple IDs from one useId call
function FormGroup({ label, description }) {
const baseId = useId();
const labelId = ${baseId}-label;
const descriptionId = ${baseId}-description;

return (
<div>
<label id={labelId}>{label}</label>
<p id={descriptionId}>{description}</p>
<input
aria-labelledby={labelId}
aria-describedby={descriptionId}
/>
</div>
);
}

Why

useId generates a deterministic ID based on the component's position in the tree. The same tree structure produces the same IDs on server and client, preventing hydration mismatches. IDs are globally unique across the component tree because React tracks position.

Gotchas

  • useId IDs start with ':' — they are invalid as CSS selectors (can't use querySelector('#:r0:'))
  • Don't use useId for list keys — keys must be data-driven, not position-based
  • If you need multiple IDs, derive them from one useId call with string suffixes
  • Available since React 18 — use a UUID library for older versions

Code Snippets

useId for label/input association

function Checkbox({ label }) {
  const id = useId();
  return (
    <>
      <input type="checkbox" id={id} />
      <label htmlFor={id}>{label}</label>
    </>
  );
}

Context

When generating unique IDs for HTML accessibility attributes in components that render on the server

Revisions (0)

No revisions yet.