Understanding the useId hook in React
React 18 came with many features such as Automatic batching, concurrency, and new hooks. Some of these hooks have immediate uses, like useTransition
for handling transitions in React and the useSyncExternalStore
hook to read external data sources. Over the last couple of months, I have worked with developers that don’t understand the need for the useId
hook. I was also one of those developers before I understood the useId
hook and the problems it solves.
This article will dive into the useId
hook, its uses, and why it works better than some Javascript options like Math.random
or libraries like uuid
.
Isomorphic applications and the useId hook
Isomorphic applications share the same code between the server and client side, which means that the server-side code can also run on the client side, which is Javascript code. React supports isomorphism out of the box, and this exposes one downfall of using Math.random
or libraries like uuid
for generating unique ids for React applications: the id generated by uuid
or Math.random
on your application will not be the same on the server and client-side when the application is rendered. This id mismatch can lead to hydration and accessibility issues because most accessibility APIs like aria
and a11y
rely on these ids to link components together.
The useId
hook was formerly known as the useOpaqueIdentifier
hook. The useOpaqueIdentifier
was the first version of the useId
hook, but there were many concerns when using it. After much work from the React team, it was renamed to the useId
hook. Simply put, the useId
hook generates a uniquely stable id that can be used across any application’s server and client side of any application. The ids generated by the useId
hook are stable across the server and client sides. The ids also take care of accessibility issues, meaning that accessibility APIs can use these ids to link components together. Hydration issues are also taken care of with the use of this hook.
How to use the useId
hook
Using the useId
hook is very easy as all it needs is for you to call the hook and start using it, as we will see in the code block below:
import { useId } from 'react';
import './App.css';
function App() {
const firstId = useId();
const secondId = useId()
return <div className="App">
<h3>The first id generated is {firstId}</h3>
<h3>The second id generated is {secondId} and different from {firstId} </h3>
</div>;
}
export default App;
First, we import the useId
hook from React. Next, we get two random ids from the useId
hook and show the ids in our application. We should see something that looks like the image below:
Open Source Session Replay
OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.
Start enjoying your debugging experience - start using OpenReplay for free.
Working with forms and the useId hook
Another way to use the useId
hook is with forms. You can choose to pass the useId
hook to multiple fields and then prepend them with additional information as shown in the code below:
import { useId } from 'react';
import './App.css';
function App() {
const firstId = useId();
const secondId = useId();
return (
<div className="App">
<form>
<div>
<label htmlFor={`${firstId}-email`}>Email</label>
<input id={`${firstId}-email`} type="text" placeholder="Your email" />
</div>
<div>
<label htmlFor={`${secondId}-password`}>Password</label>
<input
id={`${secondId}-password`}
type="password"
placeholder="Your password"
/>
</div>
</form>
</div>
);
}
export default App;
In the code below, we are prepending additional information to the ID generated, i.e., ~email
from the useId
hook. This approach adds extra information to the ID generated and also keeps the useId
call to a minimum for each form field. You can see the result as shown in the image below:
When to use the useId
hook and when not to
We have now looked at the usefulness of the useId
hook; the next thing is knowing when to use it and when not to use it.
You should use the useId
hook when:
- You want to generate unique Ids
- You want to connect HTML elements like a label and an input.
- You are using functional components
You should not use the useId
hook when:
- You need keys after mapping over a list. Use your data
- You need to target CSS selectors. This is because the
useId
hook returns a string that includes colons, as seen in the examples above. CSS selectors do not support the strings generated from theuseId
hook. - You are working with immutable values
Conclusion
This article has looked at React’s useId
hook and how to use it. We have looked at isomorphic applications and why using libraries like uuid
or options like Math.random
for isomorphic applications is bad. We also learned when to use the useId
hook and when not. I hope this article answers any questions and clears any doubt you might have when using the useId
hook. Cheers
A TIP FROM THE EDITOR: Read more about other React hooks in our A guide to the React
useState
hook and React Form Validation with theuseForm
hook articles.