The useId is a new hook introduced in React 18. The useId hook helps generate a unique Id on both the client-side and server-side.
The previous one was called the useOpaqueIdentifierhook
in React. The useOpaqueIdentifierhook
had many bugs and limitations, so the useId
hook was delayed.
In React 18, all the issues were resolved correctly, and the React team introduced the useOpaqueIdentifierhook with the new name useId.
import React from "react";
import "./styles.css";
export default function App() {
const FullName = React.unstable_useOpaqueIdentifier();
const email = React.unstable_useOpaqueIdentifier();
const term = React.unstable_useOpaqueIdentifier();
return (
<div className="card">
<div>
<label htmlFor={FullName}>Full Name</label>
<input type="text" id={FullName} name="Full Name" />{" "}
</div>
<div>
<label htmlFor={email}>Enter Email</label>
<input type="email" id={email} name="email" />
</div>
<div>
<input type="checkbox" id={term} name="term" />
<label htmlFor={term}>Agree with term</label>
</div>
<input type="submit" value="Submit" />
</div>
);
}
The React team has not provided documentation for React 18 yet because it is still in its beta version.
The useId hook takeaways
-
useId is a hook
-
useId returns string
-
useId returns a unique id for client and server-side.
-
useId has been introduced as a full function in React 18.
Demo
What is the requirement of a useId hook?
As we know, the useId hook generates a unique id for the app. We join two HTML elements with help Id in HTML most of the time. But now, we can use the useId hook to join two elements in React.
For example, we can join the label and input tag with the id
and for
. Every id should be unique on the HTML page.
<label for="FullName">Full Name</label><br />
<input type="text" id="FullName" name="Full Name" /> <br /><br />
<label for="email">Enter Email</label><br />
<input type="email" id="email" name="email" /> <br /><br />
Where and why do we use the useId hook?
We use the useId
hook only for joining two HTML elements. If you think you can use it for id generation, it is perfect but makes sure you do not target id in CSS because its unique id generates different ids every time for you.
Example 1
import { useId } from "react";
import "./styles.css";
export default function App() {
const FullName = useId();
const email = useId();
const term = useId();
return (
<div className="card">
<div>
<label htmlFor={FullName}>Full Name</label>
<input type="text" id={FullName} name="Full Name" />{" "}
</div>
<div>
<label htmlFor={email}>Enter Email</label>
<input type="email" id={email} name="email" />
</div>
<div>
<input type="checkbox" id={term} name="term" />
<label htmlFor={term}>Agree with term</label>
</div>
<input type="submit" value="Submit" />
</div>
);
}
Example 2
import { useId } from "react";
import "./styles.css";
export default function Example2() {
let prefix1 = useId();
let prefix2 = useId();
let prefix3 = useId();
return (
<div className="card">
<div>
<label htmlFor={prefix1 + "-fullName"}>Full Name</label>
<input type="text" id={prefix1 + "-fullName"} name="Full Name" />
</div>
<div>
<label htmlFor={prefix2 + "-email"}>Enter Email</label>
<input type="email" id={prefix2 + "-email"} name="email" />
</div>
<div>
<input type="checkbox" id={prefix3 + "-term"} name="term" />
<label htmlFor={prefix3 + "-term"}>Agree with term</label>
</div>
<input type="submit" value="Submit" />
</div>
);
}
Example 3
import { version, useId } from "react";
import "./styles.css";
export default function App() {
let items = [
{
id: 1,
title:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ",
},
{
id: 2,
title:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ",
},
{
id: 3,
title:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ",
},
{
id: 4,
title:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ",
},
];
let prefix1 = useId();
return (
<div className="card">
<p> Reactjs version : {version} </p>
{items.map((item) => {
return (
<p id={prefix1 + `${item.id}`} key={item.id}>
{item.id}: {item.title}
</p>
);
})}
</div>
);
}
Example 4
import { version, useId } from "react";
import "./styles.css";
export default function App() {
const ID = useId();
const type = typeof ID;
console.log(ID);
return (
<div className="card">
<p> Reactjs version : {version} </p>
<h1>
{" "}
Id: {ID} and type of Id is: {type}{" "}
</h1>
</div>
);
}
Example 5
Pass the argument of number is used hook. It is not working according to my experiments.
import { version, useId } from "react";
import "./styles.css";
export default function App() {
const ID = useId(5);
return (
<div className="card">
<p> Reactjs version : {version} </p>
<h1>
{" "}
Id: {ID} and type of Id is: {type}
</h1>
</div>
);
}
Demo
References
Exploring React 18's three new APIs - LogRocket Blog
Add useOpaqueIdentifier Hook by lunaruan · Pull Request #17322 · facebook/react
Discussions · reactwg/react-18
Intent to Ship: useId · Discussion #111 · reactwg/react-18
Conclusion
The useId hook is new in React 18; I'm very happy for the React team and community. You use the useId hook for aria-labelId, and some HTML attribute.
The useId hook has many possible uses. In the future, we will also see more use cases of the useId hook.
My article is based on my study and experiments. Complete information comes with the React docs.