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

使用Formik的FieldArray组件搭配select时出现key错误该如何解决

Formik多组select字段渲染Key错误修复方案

问题根因

该问题的核心触发原因是列表渲染时使用了数组的index作为组件的key属性值。在动态列表渲染场景下,key必须是和元素绑定的唯一稳定值,不能用可变的索引作为key。当删除数组靠前位置的条目后,后续所有条目的索引会整体前移,React的Diff算法无法识别每个表单组的唯一身份,会错误复用原有组件实例,导致Formik的字段状态绑定错位,最终出现非预期的新增条目以及控制台报错。

修复步骤

  • 给每个表单条目新增唯一稳定标识
    每个新增的收入条目都新增一个和用户输入无关的唯一字段id,可以用Date.now()或者轻量uuid生成逻辑生成,确保不同条目的id不会重复。
// 新增条目逻辑调整
const addIncomeItem = () => {
  setFieldValue('incomeList', [
    ...values.incomeList,
    {
      type: '',
      amount: '',
      id: Date.now() // 新增唯一id字段
    }
  ])
}
  • 替换列表渲染的key值
    将原来渲染列表时用的key={index}替换为key={item.id},保证每个表单组的key在数组顺序变化时保持稳定。
// 列表渲染逻辑调整
{values.incomeList.map((item, index) => (
  <div key={item.id}> {/* 唯一稳定key */}
    <select 
      name={`incomeList[${index}].type`}
      onChange={handleChange}
      value={values.incomeList[index].type}
    />
    {/* 其他表单字段 */}
  </div>
))}
  • 调整删除条目的逻辑
    删除条目时按照id过滤数组,而非按照索引删除,避免其他条目的索引变化影响状态绑定。
// 删除条目逻辑调整
const removeIncomeItem = (targetId) => {
  setFieldValue('incomeList', values.incomeList.filter(item => item.id !== targetId))
}

// 调用删除时传入当前条目的id
<button onClick={() => removeIncomeItem(item.id)}>remove</button>

注意事项

  • 禁止使用select选中值、输入金额等用户可修改的字段作为key,若出现重复值仍会触发key冲突问题
  • 字段名incomeList[${index}].type无需修改,只要key保持稳定,Formik会自动对应到正确的数组位置的字段状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:54:01