React Hook向数组状态添加新值时原有值被替换问题求助
React-Hook-Form 结合 Yup 表单验证时,数组状态添加新值覆盖原有条目问题的解决
问题描述
使用 react-hook-form 结合 Yup 做表单验证,目标是将表单输入的条目添加到数组状态并渲染到表格中,但点击添加按钮后,数组中原有所有值都会被新输入的值替换。尝试了多种状态更新方式(如直接扩展数组、手动拷贝数组等)均未解决。
问题根源
react-hook-form 为了优化性能,返回的表单数据 data 是一个 Proxy 代理对象,而非普通的 JavaScript 对象。直接将这个代理对象添加到数组中,数组内的所有元素实际上都指向同一个代理引用。当后续表单输入发生变化时,代理对象的属性值会同步更新,导致数组中所有已添加的条目都显示最新的表单值。
解决方案
在将表单数据添加到数组前,对 data 进行浅拷贝或深拷贝,将代理对象转换为普通对象,切断引用关联。
修改 addRecord 函数
将原来直接添加代理对象的逻辑,改为先拷贝数据:
const addRecord = (data) => { console.log("ADDING RECORD ", data); // 浅拷贝转换为普通对象(适用于无嵌套结构的表单数据) const newRecord = { ...data }; // 如果表单数据有嵌套结构,推荐使用深拷贝: // const newRecord = JSON.parse(JSON.stringify(data)); setDataList((prevList) => [...prevList, newRecord]); };
完整修改后的核心代码片段
// ... 其他代码保持不变 const { register, handleSubmit } = useForm({ resolver: yupResolver(schema) }); const addRecord = (data) => { console.log("ADDING RECORD ", data); const newRecord = { ...data }; setDataList((prevList) => [...prevList, newRecord]); }; useEffect(() => { console.log("ACTUAL", dataList); }, [dataList]); // ... 其他代码保持不变
为什么之前的尝试无效?
- 直接使用
setDataList([...dataList, data])或扩展数组的方式,只是对数组进行了浅拷贝,数组中的元素仍然是原来的代理对象引用,无法切断与表单的关联。 - 手动拷贝数组后
push的操作,同样没有处理代理对象的引用问题,本质和直接添加代理对象一致。
内容的提问来源于stack exchange,提问作者suryanto
相关产品推荐
相关产品推荐

