What does useId() do?
What does useId() do
useId() generates a unique, stable ID
that stays the same across renders and between the server and the client.
In simpler terms:
useId()is a way to get a safeidthat can be used forhtmlFor,aria-labelledby, keys, and so on. React guarantees that these IDs will not "break" during SSR or updates.
Syntax
const id = useId();Returns a string, for example:
"id:abc-123"Usage example
import { useId } from "react";
function EmailField() {
const id = useId();
return (
<div>
<label htmlFor={id}>Email</label>
<input id={id} type="email" />
</div>
);
}React will generate a unique id like "r1:0",
and this id will be the same during server and client rendering.
In other words - no conflicts between elements during hydration (which was a pain before React 18).
Why this matters (especially with SSR)
Previously, developers wrote something like:
const id = Math.random().toString(36).slice(2);The problem:
-
The server and the client generated different values.
-
React could not "match" the HTML, and hydration broke:
javascriptWarning: Prop `id` did not match. Server: "abc" Client: "xyz"
useId() solves this:
- React itself guarantees that the
idis synchronized between the server and the client. - It is also unique across the whole component tree.
What the ID looks like
React generates strings roughly like this:
r0:1
r1:2
r3:0r0,r1- unique prefixes of the component tree.:0,:1- element numbers.
These IDs do not collide between components.
Example: a group of related elements
If you need to create several related ids,
you can use a single useId and add suffixes manually:
function CheckboxGroup() {
const baseId = useId();
return (
<div>
<input type="checkbox" id={`${baseId}-a`} />
<label htmlFor={`${baseId}-a`}>Option A</label>
<input type="checkbox" id={`${baseId}-b`} />
<label htmlFor={`${baseId}-b`}>Option B</label>
</div>
);
}React guarantees that baseId will be stable and unique,
so you can safely build other identifiers based on it.
Can be used in lists
function Items({ list }) {
const baseId = useId();
return (
<ul>
{list.map((item, i) => (
<li key={i} id={`${baseId}-${i}`}>
{item}
</li>
))}
</ul>
);
}Each element gets a stable id,
and React will not mix them up during SSR.
Important to remember
| Feature | Explanation |
|---|---|
| Generates a unique, stable id | Does not change across renders |
| Safe for SSR | Matches between the server and the client |
Cannot be used in loops for key | The ID is not meant for React keys |
| Better not used as dynamic identifiers (for example, from a database) | It is for internal UI, not for data |
| Cannot be called in a condition | Like all hooks - only at the top level of a function |
When to use useId()
| When | Why |
|---|---|
For htmlFor and id pairs | |
| For ARIA attributes | aria-labelledby, aria-describedby |
| For auto-generating unique identifiers in the UI | Accordions, forms, tooltips |
Not for keys (key in lists) | Keys are needed by React, not the DOM |
Summary
| Question | Answer |
|---|---|
What does useId() do | Generates a unique and stable ID for elements |
| When to use it | When you need to safely link a label and an input, aria attributes, and so on |
| Why it matters | It avoids conflicts during server-side rendering (SSR) |
| What not to use it for | key in lists, identifiers from a database |
Main idea:
useId()exists to safely generate unique and stable IDs that are the same on the server and the client - without "desynchronization".
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.