跳到主要内容

useId

面试速答(30 秒版 TL;DR)​

  • useId 是 React 18 新增的 Hook,用来生成稳定且适合 SSR/CSR 对齐的唯一 ID。
  • 它最常见的用途是做无障碍关联,例如 label 和 input 的 id / htmlFor。
  • 它不是列表 key 生成器,也不是数据库主键生成器。
  • 核心价值是:避免服务端渲染和客户端 hydration 时 ID 不一致。

1. 为什么 React 18 需要它​

在 SSR 场景里,如果你自己用:

  • Math.random()
  • 自增变量
  • Date.now()

生成 ID,服务端和客户端很可能不一致,导致 hydration 对不上。

useId 解决的是“同一组件树在服务端和客户端生成一致标识”的问题。

2. 基本用法​

function Field() {
const id = useId()

return (
<>
<label htmlFor={id}>用户名</label>
<input id={id} />
</>
)
}

如果一个组件里有多组元素,可以在同一个前缀上拼接:

const id = useId()
const inputId = `${id}-input`
const hintId = `${id}-hint`

3. 它最适合的场景​

3.1 可访问性(a11y)​

  • label 和 input
  • aria-describedby
  • aria-labelledby

3.2 可复用组件库​

组件库经常不能要求调用方手动传所有 DOM ID,这时 useId 很适合做内部关联。

4. 不适合的场景​

4.1 列表 key​

React 的 key 应该来自稳定业务标识,例如:

  • 数据库 id
  • 业务唯一字段

而不是 useId()。

4.2 数据持久化 ID​

它只是 UI 层渲染时的稳定标识,不应用来当业务主键。

5. 面试高频答法​

Q1:useId 和随机字符串有什么区别?​

最大区别是:useId 设计目标就是让 React 在 SSR 和 hydration 场景里能保持一致,而随机字符串做不到这一点。

Q2:为什么不能拿它做 key?​

因为列表 key 的核心目的是描述“这条数据是谁”,而不是“这次渲染生成了什么 ID”。它应该和业务数据稳定绑定。

Q3:React 18 为什么新增它?​

因为并发渲染和 SSR/hydration 场景更常见,React 需要一个官方方案来解决组件内 DOM 关联 ID 的一致性问题。

常见追问​

1)每次 render 它会变吗?​

不会随普通重渲染随机变化,它的目的就是稳定。

2)它是不是全局唯一?​

在 React 树和使用语境里可认为足够唯一,但它的目标不是做跨系统全局唯一主键。

易错点/坑​

  • 用 useId 生成列表 key。
  • 用它充当数据库主键。
  • 不知道它是 React 18 新增,答不出它出现的背景。

速记要点(可背诵)​

  • useId:React 18 新增,用于 SSR/CSR 一致的稳定 DOM ID。
  • 典型用途:label / input、aria-* 关联。
  • 不用于列表 key,不用于业务主键。