跳到主要内容

useId

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

  • useId 是 React 18 新增的 Hook,用来生成稳定且适合 SSR/CSR 对齐的唯一 ID。
  • 它最常见的用途是做无障碍关联,例如 labelinputid / 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)

  • labelinput
  • 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 / inputaria-* 关联。
  • 不用于列表 key,不用于业务主键。