useId — React Hook

AkashSDas
2 min readMar 28, 2024

--

useId is a React Hook for generating unique IDs that can be passed to accessibility attributes.

Following is the signature of useId hook:

const id = useId()

It takes no argument and returns a unique id associated with that particular useId call and in that particular component. It shouldn’t be used to generate unique ids for other purpose (other than accessibility attributes).

useId can be used both on server and client.

With server rendering, useId requires an identical component tree on the server and the client. If the trees we render on the server and the client don’t match exactly, the generated IDs won’t match.

IDs generated by useId shouldn’t and can’t be used as CSS selectors (because of their pattern of id that’s generated).

Following in an example of using useId:

import { useId } from "react";

export default function App(): JSX.Element {
const usernameHintId = useId();

return (
<div>
{/* With useId */}
<input type="text" aria-describedby={usernameHintId} />
<p id={usernameHintId}>Enter your username</p>

{/* Without useId */}
<label>
Password:
<input type="password" aria-describedby="password-hint" />
</label>
<p id="password-hint">
The password should contain at least 18 characters
</p>
</div>
);
}

Why useId is better than incrementing a global variable like nextId++?

The primary benefit of useId is that React ensures that it works with server rendering. During server rendering, our components generate HTML output. Later, on the client, hydration attaches our event handlers to the generated HTML. For hydration to work, the client output must match the server HTML.

The primary benefit of useId is that React ensures that it works with server rendering. This is very difficult to guarantee with an incrementing counter because the order in which the Client Components are hydrated may not match the order in which the server HTML was emitted. By calling useId, we ensure that hydration will work, and the output will match between the server and the client.

Inside React, useId is generated from the “parent path” of the calling component. This is why, if the client and the server tree are the same, the “parent path” will match up regardless of rendering order.

--

--