【React】useId

在 React 中,useId 是 React 18 引入的一个 Hook,用于生成一个在组件生命周期中保持稳定的唯一 ID。它主要用于:

  • 无障碍(accessibility)场景 ,比如表单控件需要一个 idlabelhtmlFor 属性配对。
  • 服务端渲染(SSR) 与客户端渲染保持一致。
  • 避免多个组件生成的 ID 冲突。

🧠 为什么不用自己写 id

以前开发者会自己写逻辑生成 id,比如用 Math.random()Date.now()uuid 生成,但这些在服务端渲染(SSR)和客户端渲染中可能不一致,从而导致 水合(hydration)错误

SSR:服务端渲染出 html 内容,发给浏览器,浏览器接收到 html,先展示静态内容,然后加载动态js,就是将html激活(水合),然后就生成了动态应用,但是这样服务端和浏览器端的 id 生成就会不同(可能随机数生成等等)。


useId 的基本语法

jsx 复制代码
const id = useId();
  • id 是一个 字符串,React 会自动加前缀,确保唯一性。

🧪 示例:表单中 label 与 input 关联

jsx 复制代码
import React, { useId } from 'react';

function NameInput() {
  const id = useId();

  return (
    <div>
      <label htmlFor={id}>姓名:</label>
      <input id={id} type="text" />
    </div>
  );
}

在这个例子中:

  • labelhtmlForinputid 使用同一个值。
  • useId() 保证了 ID 在每次渲染中一致,适用于 SSR。

🧩 示例:多个组件实例

jsx 复制代码
function InputField({ label }) {
  const id = useId();

  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} type="text" />
    </div>
  );
}

function Form() {
  return (
    <>
      <InputField label="用户名" />
      <InputField label="邮箱" />
    </>
  );
}

每个 InputField 都会生成不同的 id,即使组件重复使用也不会冲突。


⚠️ 注意事项

  1. useId 不能用在事件处理函数或条件判断内部
  2. 它不能替代 key、uuid 等复杂 ID 生成需求(比如数据库 ID)。
  3. 如果你要生成 带后缀的 ID,可以这样做:
jsx 复制代码
const id = useId();
<input id={`${id}-email`} />

🎯 适用场景总结

场景 是否推荐用 useId
labelinput/textarea 等的 ID 配对 ✅ 是
ARIA 属性如 aria-labelledby ✅ 是
SSR 页面保持一致性 ✅ 是
用于生成数据库 ID、URL 等 ❌ 否

如果在使用 React 17 或更低版本,可以用第三方库如 uuidnanoid 作为替代,但在 React 18+ 推荐用 useId 来保证一致性和性能。

相关推荐
JieE2124 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
runnerdancer4 小时前
LLM是怎么处理messages数组的,提示词缓存又是什么
前端·agent
陈随易5 小时前
VSCode的Copilot扩展支持接入DeepSeek,Kimi了!
前端·后端·程序员
我不是外星人6 小时前
有了 Harness Engineering ,真的还需要研发工程师吗?
前端·后端·ai编程
candyTong6 小时前
RTK 技术原理:一次典型会话里,80% 上下文是怎么省下来的
javascript·后端·架构
IT_陈寒9 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
Jackson__10 小时前
分享一个横向滚动案例,带悬停暂停,通用性很强
前端
MariaH10 小时前
git rebase的使用
前端
_柳青杨10 小时前
深入理解 JavaScript 事件循环
前端·javascript
阡陌Jony10 小时前
关于前端性能优化的一些问题:
前端