Form inputs need unique IDs so labels, help text, and accessibility attributes can correctly connect to the right element. But in reusable components, hardcoding IDs quickly breaks down. That’s exactly what
useIdsolves.
A label connects to an input using htmlFor and id.
function TextField() {return (<><label htmlFor="email">Email</label><input id="email" /></>);}
This works fine once. But reusable components are meant to be rendered many times:
<TextField /><TextField />
Now both inputs use the same id="email". That creates duplicate IDs in the DOM, which is invalid HTML and can confuse screen readers.
React provides the useId hook to generate a unique, stable ID for each component instance.
import { useId } from "react";function TextField({ label, hint }) {const id = useId();const hintId = `${id}-hint`;return (<div><label htmlFor={id}>{label}</label><input id={id} aria-describedby={hintId} /><p id={hintId}>{hint}</p></div>);}
Now every rendered TextField gets its own unique ID automatically.
<TextField label="Email" /><TextField label="Password" />
useId is only for DOM relationships. Do not use it for:
// ❌ Wrongitems.map(item => <Row key={useId()} />)