Other

useId

Generates a unique ID that is stable across server and client renders. Designed for accessibility attributes like htmlFor, aria-describedby, and aria-labelledby.

Signature

TypeScript
const id = useId()

Return Value

A unique string ID (e.g., ':r1:') that is consistent between server and client renders, suitable for HTML id attributes.

Examples

Form Label Pairing
import { useId } from 'react';

function FormField({ label, type = 'text' }: { label: string; type?: string }) {
  const id = useId();

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

// Each instance gets a unique ID:
// <FormField label="Name" />    → id=":r1:"
// <FormField label="Email" />   → id=":r2:"
Accessible Error Messages
import { useId, useState } from 'react';

function ValidatedInput({ label, validate }: {
  label: string;
  validate: (v: string) => string | null;
}) {
  const id = useId();
  const errorId = `${id}-error`;
  const [value, setValue] = useState('');
  const error = validate(value);

  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input
        id={id}
        value={value}
        onChange={e => setValue(e.target.value)}
        aria-invalid={!!error}
        aria-describedby={error ? errorId : undefined}
      />
      {error && <p id={errorId} role="alert" style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
Multiple Related IDs
import { useId } from 'react';

function Accordion({ title, children }: { title: string; children: React.ReactNode }) {
  const id = useId();
  const headerId = `${id}-header`;
  const panelId = `${id}-panel`;

  return (
    <div>
      <h3>
        <button
          id={headerId}
          aria-expanded="true"
          aria-controls={panelId}
        >
          {title}
        </button>
      </h3>
      <div
        id={panelId}
        role="region"
        aria-labelledby={headerId}
      >
        {children}
      </div>
    </div>
  );
}

Common Pitfalls

!

Using useId to generate keys for list items — use stable data identifiers instead. useId is for HTML attributes.

!

Calling useId conditionally or in loops — it's a hook and must follow the rules of hooks.

!

Using Math.random() or Date.now() for IDs instead of useId — these cause hydration mismatches in SSR.

!

Adding useId-generated values to CSS selectors — the colon characters in the ID require escaping in CSS.

Understanding useId

useId solves a fundamental problem in server-rendered React applications: generating unique HTML IDs that are consistent between the server and client. Before useId, developers often used incrementing counters or random values, which would produce different IDs during server rendering and client hydration, causing hydration mismatch warnings and accessibility issues.

The IDs generated by useId follow a specific pattern (like :r1:, :r2:) that is deterministic based on the component's position in the React tree. This means the same component rendered in the same position will always produce the same ID, regardless of whether it's rendered on the server or client. The colons in the ID format are intentional — they make it unlikely to collide with user-defined IDs.

The primary use case is associating labels with form inputs using the htmlFor attribute, which is essential for accessibility. When multiple instances of the same form component are rendered, each needs a unique ID to correctly pair the label with its input. useId handles this automatically. You can also derive multiple related IDs from a single useId call by appending suffixes.

useId should not be used for list keys or as a general-purpose unique identifier generator. React's reconciliation algorithm requires keys to be stable across re-renders and based on the data being rendered, not on the component instance. For list keys, use a field from your data like an ID or a unique combination of fields. useId is specifically designed for HTML id attributes and related accessibility patterns.

Related Hooks

More Other Hooks

Explore All React Hooks

Browse our complete reference of 19 React hooks with signatures, examples, pitfalls, and in-depth explanations.