如何修复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;
关键改动说明
- 替换UUID生成方式:去掉lodash依赖,改用浏览器原生的
crypto.randomUUID(),生成符合RFC 4122标准的UUID v4,在多客户端、页面刷新场景下都能保证唯一性。 - 移除冗余状态:不再维护
uuid状态,而是在提交表单时实时生成,避免无效的状态管理。 - 优化用户体验:用表单状态重置替代
window.location.reload(),避免页面刷新导致的体验中断。 - 修复数据类型问题:将数量输入转换为数字类型,避免后端接收字符串格式的数值。
- 添加错误捕获:用
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();即可。
原代码问题分析
- lodash.uniqueId()的局限性:该方法仅在当前页面会话中生成递增字符串(如"1"、"2"),页面刷新后会重置计数,多用户同时操作时必然生成重复ID,不满足唯一标识的需求。
- 无效状态更新:原代码中
window.location.reload()之后调用setUuid,但页面刷新后组件会重新初始化,状态更新完全无效,导致提交时可能使用旧ID或初始值"0"。
内容的提问来源于stack exchange,提问作者Jackson Pedvis
相关产品推荐
相关产品推荐

