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

React Formik中为已有对象数组新增属性赋值接口数据失败怎么办

问题根因

你的代码不生效核心是违反了Formik的状态更新规则:

  • Formik的表单状态遵循不可变更新原则,直接通过myInfo[idx].vals = myData突变(mutate)原始状态对象,不会触发Formik的状态校验和重渲染,新属性自然不会同步到表单值里
  • 你没有调用Formik官方提供的状态更新方法,直接修改游离的变量引用,不会被Formik的状态管理捕获
  • 额外隐患:直接用数组索引匹配请求结果,如果接口返回顺序和请求发送顺序不一致,会出现vals属性赋值错位的问题
修复方案

首先从Formik实例中取出setFieldValue方法(无论你用useFormik钩子还是<Formik>组件的render props都可以拿到这个方法),所有表单值的更新都通过这个方法执行,并且更新时要生成新的数组/对象,不要直接修改原状态。

完整实现代码

// 如果你用useFormik初始化表单
const formik = useFormik({
  initialValues: {
    // 其他表单字段...
    myInfo: [
      {
        myId: 0,
        myName: "Name A",
        defaultVal: 2
      },
      {
        myId: 1,
        myName: "Name B",
        defaultVal: 4
      }
    ]
  },
  // 你的校验规则、提交逻辑等其他配置...
});

const getAdditionalData = async (id) => {
  try {
    const response = await fetch(`http://localhost:3000/more-data/${id}`);
    const myData = await response.json();
    // 不可变更新:通过myId匹配对应项,避免请求顺序错乱导致赋值错位
    const updatedMyInfo = formik.values.myInfo.map(item => {
      if (item.myId === id) {
        // 复制原有项属性,新增vals字段
        return { ...item, vals: myData };
      }
      return item;
    });
    // 调用Formik的更新方法同步新值到表单状态
    formik.setFieldValue('myInfo', updatedMyInfo);
  } catch (err) {
    console.error(err.message);
  }
};        

useEffect(() => {
  // 不需要返回值的遍历用forEach即可,不需要用map
  formik.values.myInfo.forEach((info) => {
    getAdditionalData(info.myId);
  });
}, []); 

如果你用的是<Formik>组件嵌套写法,直接从组件的render props中解构出setFieldValue和values替换上述代码里的formik.setFieldValue、formik.values即可,逻辑完全一致。

提示:所有Formik表单值的修改都不要直接操作values里的原始对象,必须生成新的引用(新对象/新数组)后通过官方提供的setFieldValue、setValues等方法更新,否则Formik无法检测到状态变化,就会出现改了值但不生效、视图不更新的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:42:13