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

如何在Formik中获取Yup数组自定义校验的错误信息数组?

问题分析与解决方案

问题根源

  1. Yup test 方法使用规范不符:你错误地让错误消息生成函数返回了数组,而Yup要求错误消息必须是字符串。单独调用validate时,Yup会将数组形式的错误存入error.errors,但Formik在处理字段错误时,会把非字符串类型的错误默认转换为“n errors occurred”这类通用提示,导致你无法拿到具体错误信息。
  2. 校验逻辑存在冗余:原代码的双重循环会重复添加错误(比如第二、第三个元素重复时,会同时给两个位置添加错误),且返回数组的方式不符合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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:50:04