当前位置: 首页 > news >正文

WHAT - React useId vs uuid

目录

  • uuid
  • useId
    • 适用场景
    • 语法
    • 示例
    • 注意事项
  • 复杂示例
    • 示例:动态表单列表 + useId
    • 解读重点
  • useId vs uuid
    • 一句话总结
    • 对比表格
    • 示例对比
      • useId 用于表单
      • uuid() 用在 UI 会出问题
      • uuid 的适合场景
    • 总结建议

uuid

在 WHAT - Math.random?伪随机? 中我们介绍过:在需要生成唯一标识符(如订单号、用户 ID 等)时,可以使用 crypto.randomUUIDuuid 库生成唯一 ID。

我们今天主要介绍另外一个 id 相关的 React Hook:useId.

useId

useId 是 React 18 新增的一个 Hook,用于生成稳定的唯一 ID,常用于将标签 (<label>) 和表单控件 (<input>) 关联起来,或是生成无冲突的 id 属性。

适用场景

  • 表单元素的 id(确保无冲突)
  • 多次渲染同一组件时生成唯一 id
  • SSR(服务端渲染)时也能保证一致性

语法

const id = useId();

它返回一个类似 'react-uid-123' 的字符串。

示例

import { useId } from 'react';

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

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

注意:即使多个 NameInput 组件在页面中同时使用,它们的 id 也会自动不同。

注意事项

  • useId 不适用于作为 key 的值(比如 .map() 中的列表 key),因为它在每次组件挂载时都可能变化
  • 如果你在 client 和 server 同时渲染组件(SSR/CSR 混合),useId 可避免 id 不一致的问题。

复杂示例

我们做一个复杂点的例子:假设你有一个动态表单列表,每一项都有自己的输入框和 label,我们需要为每一项生成唯一的 id 来正确关联 label 和 input。

示例:动态表单列表 + useId

import React, { useId, useState } from 'react';

type Item = {
  name: string;
};

function DynamicInput({ index }: { index: number }) {
  const id = useId();

  return (
    <div className="mb-4">
      <label htmlFor={`${id}-${index}`} className="block text-sm font-medium text-gray-700">
        Name {index + 1}
      </label>
      <input
        id={`${id}-${index}`}
        type="text"
        className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
      />
    </div>
  );
}

export default function DynamicFormList() {
  const [items, setItems] = useState<Item[]>([{ name: '' }]);

  const addItem = () => {
    setItems((prev) => [...prev, { name: '' }]);
  };

  return (
    <div className="p-4 max-w-md mx-auto">
      {items.map((_, index) => (
        <DynamicInput key={index} index={index} />
      ))}

      <button
        onClick={addItem}
        className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
      >
        Add More
      </button>
    </div>
  );
}

解读重点

  • useId()DynamicInput 中使用,保证每次组件挂载时得到一个唯一 base id。
  • 为了进一步防止同一个组件多次渲染的 id 冲突,我们拼接了 indexid + '-' + index
  • React 会自动确保 useId() 在服务端和客户端渲染时一致。

如果你有 Form 表单需要连着 react-hook-form 或 Ant Design 一起用,也可以继续扩展这个结构。

useId vs uuid

useIdcrypto.randomUUID() / uuid 库确实都可以生成 唯一 ID,但它们适用的场景和行为是不同的,下面我们详细对比:

一句话总结

方法用于 UI 组件标识,适配 React SSR
useId()✅ React-friendly,适合绑定 label/input,确保 SSR/CSR 一致性
uuid / crypto.randomUUID()❌ 更适合用于数据或对象标识,不适合 React UI 中做绑定 ID

对比表格

特性 / 方法useId() (React 18+)uuid() / crypto.randomUUID()
生成时机在组件 render 时生成手动调用时生成
是否稳定(跨渲染一致)✅ 是(React 保证)❌ 否,每次渲染都不同
SSR(服务端渲染)支持✅ 是(React 内部实现保障)❌ 可能导致客户端/服务端 mismatch
用途label/input 的关联、无冲突 DOM id标识数据库记录、API 请求唯一标识等
是否唯一✅ 唯一(组件级)✅ 全球唯一(基于标准算法)
是否适合用于 React 组件 id 属性✅ 非常适合❌ 不推荐(SSR 不稳定)

示例对比

useId 用于表单

const id = useId();

<label htmlFor={id}>Email</label>
<input id={id} type="email" />
  • SSR 和 CSR 渲染出的 id 一致,不会导致 hydration 错误。

uuid() 用在 UI 会出问题

const id = uuidv4(); // 每次渲染都会变

<label htmlFor={id}>Email</label>
<input id={id} type="email" />
  • React SSR 时:服务端渲染出来是一个 uuid,客户端挂载后又生成一个新的 → ⚠️ Hydration mismatch error

uuid 的适合场景

const userId = uuidv4(); // 生成全局唯一 ID
sendNewUser({ id: userId, name: 'Jack' });
  • 用在数据、日志、标识某个操作/实体,很合适。

总结建议

用途推荐使用
表单 label/input 的绑定 iduseId()
SSR 支持的组件内部 iduseId()
数据项唯一标识、后端传输 IDuuid()crypto.randomUUID()

如果你正在做表单、modal、或 tooltip 这类跟 UI DOM 结构密切相关的组件,优先考虑 useId。 如果你要唯一标记某条数据、日志、缓存、队列项等,用 uuid()

http://www.dtcms.com/a/122756.html

相关文章:

  • Pascal VOC 2012 数据集格式与文件结构
  • 前端性能优化的全方位方案【待进一步结合项目】
  • Redis 持久化+性能管理+缓存
  • XSS靶场闯关小游戏
  • 10A 大电流 DCDC 降流芯片 WD5030
  • 2025年AI开发学习路线
  • springboot集成大华人脸机
  • js实现跨域下载,展示下载进度以及自定义下载名称功能
  • Docker新型容器镜像构建技术,如何正确高效的编写Dockerfile
  • 前端三件套—CSS入门
  • 13_pandas可视化_seaborn
  • 青少年编程与数学 02-016 Python数据结构与算法 10课题、搜索
  • Webstorm 使用搜不到node_modules下的JS内容 TS项目按Ctrl无法跳转到函数实现
  • leetcode刷题日记——验证回文串
  • 算法比赛中常用的数学知识
  • C# Winform 入门(15)之制作二维码和拼接(QR)
  • miniconda安装R语言图文教程(详细步骤)
  • 13. git clone
  • Mysql | 主从复制的工作机制
  • 西电服务器环境配置问题汇总(一)
  • 【同步教程】基于Apache SeaTunnel从MySQL同步到MySQL——Demo方舟计划
  • 山东大学软件学院项目实训开发日志(7)之测试前后端本地部署
  • TCP连接四次挥手的过程,为什么是四次?
  • STM32单片机入门学习——第30节: [9-6] FlyMcu串口下载STLINK Utility
  • Rust入门之迭代器(Iterators)
  • 实战篇-梳理时钟树
  • QT学习笔记
  • 使用 DeepSeek API 实现新闻文章地理位置检测与地图可视化
  • 华为手机或平板与电脑实现文件共享
  • 电脑清洁常用工具