Formik FieldArray调用insert(0, '')时errors数组不同步错位问题排查
问题原因
- Formik的FieldArray仅在调用方法时同步values数组,错误数组的偏移逻辑存在场景遗漏:插入元素到数组头部时,原有错误的索引不会对应后移,导致错误和值的索引错位
- 校验规则返回的错误数组为稀疏结构:默认校验逻辑只会给存在校验失败的索引返回错误信息,无错误/未触碰的索引不会返回占位值,新增元素后错误数组长度和values数组长度不一致,进一步加剧绑定错位
- 延时调用
validateForm()无效的原因:默认校验规则不会为未触碰(touched=false)的空白字段生成错误占位,执行校验后错误数组的长度仍然和values不匹配,错位问题无法修复
解决方案
方案1:手动偏移错误数组(快速修复)
在调用insert方法后,手动调整对应字段的错误数组结构,给新增的位置插入占位符:
onClick={() => { const fieldKey = 'yourArrayField' // 替换为你的FieldArray对应字段名 const originErrors = formik.errors[fieldKey] || [] // 插入元素到头部 arrayHelpers.insert(0, '') // 手动给错误数组头部新增占位,原有错误全部后移一位 formik.setErrors({ ...formik.errors, [fieldKey]: [undefined, ...originErrors] }) }}
方案2:优化校验规则返回全长度错误数组
如果使用Yup做校验,确保数组校验规则会遍历所有元素,返回和values长度完全一致的错误数组:
const schema = Yup.object().shape({ yourArrayField: Yup.array() .of(Yup.string().required('请输入有效编码')) // 每个元素都会被校验,无错误的索引会返回undefined占位 })
方案3:基于唯一ID绑定字段(根本解决)
不要用数组索引作为字段名的唯一标识,给每个数组元素新增唯一ID,用ID绑定对应字段,彻底避免索引变化导致的错位问题:
// 新增元素时生成唯一ID arrayHelpers.insert(0, { id: nanoid(), value: '' }) // Field组件绑定用ID而非索引 {values.yourArrayField.map((item) => ( <Field name={`yourArrayField[${item.id}].value`} key={item.id} /> ))}
内容的提问来源于stack exchange,提问作者A. Rabus
相关产品推荐
相关产品推荐

