When to Avoid useId Hook in React
The useId hook in React is a highly effective tool for
generating unique, stable IDs for accessibility attributes and linking
form elements. However, it is not a universal solution for all
identification needs in a web application. This article outlines the
specific scenarios where you should avoid using the useId
hook and explains what you should use instead.
Generating Keys for List Items
You should never use useId to generate the
key prop for items in a list. React uses keys to track
which items in a list have changed, been added, or been removed. Because
useId generates IDs based on the component’s render tree
position, reordering a list will cause the generated IDs to shift to
different data items. This defeats the purpose of keys, leading to
rendering bugs, lost state in input fields, and degraded performance.
Instead, always use stable IDs derived directly from your data source,
such as database primary keys.
Targeting Elements in CSS Selectors
Avoid using useId if you plan to target those IDs in
global CSS stylesheets. The IDs generated by useId contain
colons (for example, :r0:), which are special characters in
CSS. To target them, you would have to escape the colons in your CSS
selectors (e.g., \#\:r0\:), which makes your stylesheets
difficult to read and maintain. Furthermore, because these IDs are
generated dynamically based on render order, they are not guaranteed to
remain identical if the layout of your application changes. Use static,
semantic class names for styling instead.
Querying Elements in Automated E2E Tests
Do not rely on useId for locating elements in end-to-end
(E2E) testing frameworks like Cypress, Selenium, or Playwright. Since
the generated IDs depend on the order in which React components are
mounted, adding or removing a component elsewhere on the page can shift
the IDs of unrelated elements. This makes your automated tests fragile
and prone to random failures. For testing purposes, it is best to use
stable, dedicated attributes like data-testid.
Creating Database Keys or Security Tokens
The useId hook is designed solely for client-side and
server-side DOM linking. The generated strings are not cryptographically
secure, nor are they globally unique across different user sessions or
application instances. You should never use useId to
generate unique identifiers for database records, API request tokens, or
security salts. For these use cases, utilize robust UUID libraries or
cryptographically secure random number generators.
Simple, Single-Instance Static Elements
If a component is static and guaranteed to only ever render once on a
single page, using useId introduces unnecessary overhead.
For a single contact form or a search bar that has no chance of being
duplicated on the page, hardcoded, descriptive string IDs (like
id="main-search-input") are cleaner, easier to debug, and
more performant.