You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复React表单中Lodash.uniqueId()生成重复ID的问题

修复React组件中唯一UUID生成问题

修改后的代码(使用浏览器原生API生成标准UUID)

import { useState } from "react";

function AddDrug(){
    const [dname, setDname] = useState("");
    const [dsummary, setDsummary] = useState("");
    const [dquantity, setDquantity] = useState(0);

    const handleSubmit = async (e) => {
        e.preventDefault();

        // 提交时实时生成唯一UUID
        const uuid = crypto.randomUUID();

        const data = {
            name: dname,
            summary: dsummary,
            quantity: dquantity,
            UUID: uuid
        };

        try {
            await fetch('http://localhost:9000/api/drugs/add', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(data)
            });
            // 重置表单状态,替代页面刷新
            setDname("");
            setDsummary("");
            setDquantity(0);
        } catch (err) {
            console.error('药品添加失败:', err);
        }
    };

    const handleNameChange = (e) => {
        setDname(e);
    };

    const handleSummaryChange = (e) => {
        setDsummary(e);
    };

    const handleQuantityChange = (e) => {
        // 确保数量为数字类型
        setDquantity(Number(e));
    };

    return (
        <form onSubmit={handleSubmit}>
            <label htmlFor={"name"}> 药品名称:</label>
            <input 
                type={"text"} 
                id={"name"} 
                name={"name"} 
                value={dname} 
                onChange={e => handleNameChange(e.target.value)} 
            />
            <label htmlFor={"summary"}>药品说明:</label>
            <input 
                type={"text"} 
                id={"summary"} 
                name={"summary"} 
                value={dsummary} 
                onChange={e => handleSummaryChange(e.target.value)} 
            />
            <label htmlFor={"quantity"}>库存数量:</label>
            <input 
                type={"number"} 
                id={"quantity"} 
                name={"quantity"} 
                value={dquantity} 
                onChange={e => handleQuantityChange(e.target.value)} 
            />
            <button type={"submit"}>添加药品</button>
        </form>
    );
}

export default AddDrug;

关键改动说明

  1. 替换UUID生成方式:去掉lodash依赖,改用浏览器原生的crypto.randomUUID(),生成符合RFC 4122标准的UUID v4,在多客户端、页面刷新场景下都能保证唯一性。
  2. 移除冗余状态:不再维护uuid状态,而是在提交表单时实时生成,避免无效的状态管理。
  3. 优化用户体验:用表单状态重置替代window.location.reload(),避免页面刷新导致的体验中断。
  4. 修复数据类型问题:将数量输入转换为数字类型,避免后端接收字符串格式的数值。
  5. 添加错误捕获:用try/catch包裹请求,便于调试提交失败的场景。

兼容旧浏览器方案

如果需要兼容不支持crypto.randomUUID()的旧浏览器,可以使用自定义的UUID生成函数:

function generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

然后在handleSubmit中替换为const uuid = generateUUID();即可。

原代码问题分析

  1. lodash.uniqueId()的局限性:该方法仅在当前页面会话中生成递增字符串(如"1"、"2"),页面刷新后会重置计数,多用户同时操作时必然生成重复ID,不满足唯一标识的需求。
  2. 无效状态更新:原代码中window.location.reload()之后调用setUuid,但页面刷新后组件会重新初始化,状态更新完全无效,导致提交时可能使用旧ID或初始值"0"。

内容的提问来源于stack exchange,提问作者Jackson Pedvis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:29:58