useId
useId
是 React 18 引入的一个内置 Hook,用于生成唯一且稳定的 ID
,
主要用于
,解决在客户端和服务器端渲染(SSR)时,动态生成 ID 可能导致的冲突问题;
特别适合用于
,需要关联 HTML 元素(如:
useId 的注意事项
-
不要在循环或条件语句内调用:
useId 必须在组件的顶层调用,否则可能导致不一致的 ID。 -
不要用于 key 属性(除非组合使用)
useId 生成的 ID 通常较短,不适合直接作为 key(除非结合其他唯一值)。 -
与 useRef 或 useState 不同:
useId 不触发重新渲染,也不存储数据,仅用于生成唯一标识。
场景
-
<label htmlFor="input-id"> 和 <input id="input-id">
的关联 -
在列表中为每个项生成唯一标识(如:key 属性)
-
在无障碍(a11y)场景下,需要唯一标识关联元素
基本用法
import { useId } from 'react'function FormField() {const id = useId() // 生成唯一 ID,如 ":r1:"return (<div><label htmlFor={id}> Username: </label><input id={id} type="text" /></div>)
}useId() 返回一个唯一的字符串(如 ":r1:"、":r2:")。每次调用 useId() 都会生成一个新的唯一 ID。生成的 ID 在客户端和服务器端一致,不会导致 hydration 错误。
关联 label 和 input
function LoginForm() {const usernameId = useId()const passwordId = useId()return (<form><div><label htmlFor={usernameId}> Username: </label><input id={usernameId} type="text" /></div><div><label htmlFor={passwordId}> Password: </label><input id={passwordId} type="password" /></div></form>)
}
生成列表项的唯一 key
function TodoList({ items }) {return (<ul>{items.map((item) => {const id = useId() // ❌ 错误!不能在循环内调用 useIdreturn <li key={id}> {item.text} </li>})}</ul>)
}`注意`:useId 不能 在'循环' 或 '条件语句内'调用,因为它依赖于 React 的渲染顺序。
正确的做法是:function TodoList({ items }) {const baseId = useId() // 在组件顶层调用return (<ul>{items.map((item, index) => (<li key={`${baseId}-${index}`}>{item.text}</li>))}</ul>)
}