如何在Formik中获取Yup数组自定义校验的错误信息数组?
问题分析与解决方案
问题根源
- Yup
test方法使用规范不符:你错误地让错误消息生成函数返回了数组,而Yup要求错误消息必须是字符串。单独调用validate时,Yup会将数组形式的错误存入error.errors,但Formik在处理字段错误时,会把非字符串类型的错误默认转换为“n errors occurred”这类通用提示,导致你无法拿到具体错误信息。 - 校验逻辑存在冗余:原代码的双重循环会重复添加错误(比如第二、第三个元素重复时,会同时给两个位置添加错误),且返回数组的方式不符合Yup的API要求。
修正后的数组唯一校验实现
调整test方法逻辑,返回布尔值表示校验结果,同时生成包含所有重复位置的清晰错误字符串:
export const arrayValidation = Yup.array() .min(1) .max(5) .of(Yup.string().required("Required")) .test('unique', function(value) { const seen = new Map(); const duplicatePositions = []; // 遍历数组,记录重复元素的位置(从1开始计数) value.forEach((item, index) => { if (seen.has(item)) { // 避免重复记录同一组重复项的起始位置 if (!duplicatePositions.includes(seen.get(item) + 1)) { duplicatePositions.push(seen.get(item) + 1); } duplicatePositions.push(index + 1); } else { seen.set(item, index); } }); // 去重并排序,生成友好的错误提示 const uniqueDuplicates = [...new Set(duplicatePositions)].sort((a, b) => a - b); if (uniqueDuplicates.length > 0) { const positionStr = uniqueDuplicates.map(pos => { const ordinalMap = { 1: '第一', 2: '第二', 3: '第三', 4: '第四', 5: '第五' }; return ordinalMap[pos] || `第${pos}`; }).join('、'); return this.createError({ message: `${positionStr}字段存在重复值`, path: this.path // 关联到对应的Formik字段 }); } return true; // 校验通过 });
Formik中使用效果
现在formik.errors.arrayStrings会直接返回格式化后的错误字符串(比如“第二、第三个字段存在重复值”),可以直接在组件中展示。
额外说明
如果你确实需要获取错误数组而非字符串,Formik本身不支持字段错误为数组的场景,你需要自行通过变量存储错误信息,或使用formik.setErrors手动设置,但这种方式不如直接生成清晰的错误字符串直观。
内容的提问来源于stack exchange,提问作者xNevrroXx
相关产品推荐
相关产品推荐

