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

如何在Formik的FieldArray嵌套数组中实现单对象切换开关功能

解决Formik FieldArray嵌套对象开关状态不生效问题

你遇到的状态不生效问题,通常由两种原因导致:setFieldValue传入的字段路径错误,或是直接修改了Formik的状态对象导致无法触发重渲染。可以按以下方案实现:


实现步骤

1. 绑定开关的正确字段路径

FieldArray内的每个元素都对应唯一的索引路径,开关直接绑定[数组字段名].[索引].isEditing即可,Formik会自动处理状态同步,无需手动修改状态。示例代码如下:

import { Formik, Form, Field, FieldArray } from 'formik';

const initialValues = {
  // FieldArray对应的字段为items
  items: [
    { name: '示例1', isEditing: false },
    { name: '示例2', isEditing: false }
  ]
};

function MyForm() {
  return (
    <Formik initialValues={initialValues} onSubmit={values => console.log(values)}>
      {({ values }) => (
        <Form>
          <FieldArray name="items">
            {({ push, remove }) => (
              <>
                {values.items.map((item, index) => (
                  // 建议替换为每个对象的唯一ID作为key,避免数组操作时状态错位
                  <div key={index}>
                    {/* 切换开关直接绑定对应路径的isEditing */}
                    <Field 
                      type="checkbox" 
                      name={`items.${index}.isEditing`}
                    />
                    <label>开启编辑</label>
                    {/* 输入框根据当前item的isEditing状态判断是否禁用 */}
                    <Field 
                      name={`items.${index}.name`}
                      disabled={!item.isEditing}
                      placeholder="请输入内容"
                    />
                    <button type="button" onClick={() => remove(index)}>删除当前项</button>
                  </div>
                ))}
                <button 
                  type="button" 
                  onClick={() => push({ name: '', isEditing: false })}
                >
                  新增项
                </button>
              </>
            )}
          </FieldArray>
          <button type="submit">提交</button>
        </Form>
      )}
    </Formik>
  );
}

2. 手动修改状态的正确写法

如果需要自定义切换逻辑,手动调用setFieldValue时必须传入完整的字段路径:

const handleToggle = (index, setFieldValue, currentStatus) => {
  // 传入完整路径+新值,不要直接修改values对象
  setFieldValue(`items.${index}.isEditing`, !currentStatus);
};

注意事项

  • 禁止直接修改Formik的values对象,比如values.items[index].isEditing = true这类直接突变的写法,Formik无法检测到状态变更,不会触发重渲染
  • 如果嵌套Fields抽离为单独组件,可通过useFormikContext钩子在子组件内获取最新的values,或直接把isEditing作为props传入子组件,确保状态能同步到子层

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:45:05