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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:23:08