标准答案
- useId 会生成适合当前 React 树的稳定 id,服务端渲染和客户端 hydration 时能保持一致。
- 它适合把 label 和 input、说明文本和控件、错误提示和字段用 aria 属性关联起来。
- 它不适合用作列表 key。列表 key 应来自数据身份,而不是组件内部生成的 id。
- 多个组件实例调用 useId 时,React 会保证同一棵树内的 id 不冲突。
- 如果 id 需要和业务数据、URL、后端记录对应,应使用业务 id,而不是 useId。
题目解析
这道题要同时讲 SSR 和可访问性。随机 id 在服务端和客户端可能不同,会造成 hydration 警告。
useId 的价值在组件库里很明显:组件需要默认生成 label/input 关联 id,同时允许外部传入 id 覆盖。
不要把 useId 当成通用唯一 id 工具。它是 React 渲染树里的稳定 id,不是数据库 id 或列表 key。
代码示例
下面的字段组件用 useId 建立 label、input 和错误提示之间的关联。
TSX
function TextField({ label, error }: { label: string; error?: string }) {
const id = useId()
const errorId = `${id}-error`
return (
<div>
<label htmlFor={id}>{label}</label>
<input
id={id}
aria-invalid={Boolean(error)}
aria-describedby={error ? errorId : undefined}
/>
{error ? <p id={errorId}>{error}</p> : null}
</div>
)
}常见误区
- 用 Math.random 生成表单 id,SSR 时服务端和客户端 id 不一致。
- 把 useId 生成的值当列表 key 使用。
- 只渲染视觉上的 label,没有用 htmlFor、aria-describedby 建立可访问性关联。