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

如何在Formik+Yup数组对象校验中实现邮箱唯一性验证?

问题

我有一个对象数组,正在使用Formik和Yup按照以下Schema做数据校验:

validationSchema: Yup.object().shape({
  fileData: Yup.array()
    .of(
      Yup.object().shape({
        Nome: Yup.string()
          .test("Nome", "Este campo é obrigatório", (value: any) => {
            if (value && value.length > 0) return true;
            else return false;
          })
          .required("Introduz uma data futura")
          .typeError("Introduz uma data futura"),
        "Data nascimento (DD-MM-AAAA)": Yup.string()
          .test(
            "Data nascimento (DD-MM-AAAA)",
            "Tem de ter entre",
            (value: any) => {
              let date = moment(value, "DD-MM-YYYY");

              return moment().diff(moment(date), "years") >= 18;
            }
          )
          .typeError("escolha uma data válida"),
        "Género (F ou M)": Yup.string()
          .test(
            "Género (F ou M)",
            "Este campo é obrigatório",
            (value: any) => {
              if (
                value &&
                value.length > 0 &&
                (value == "M" || value == "F")
              )
                return true;
              else return false;
            }
          )
          .required("Introduz uma data futura")
          .typeError("Introduz uma data futura"),
        Email: Yup.string()
          .test("Email", "Este campo é obrigatório", (value: any) => {
            if (value) return true;
            else {
              return true;
            }
          })
          .typeError("Introduz uma data futura"),
      })
    )
    .nullable(),
}),

目前Email字段为空时会触发错误,我希望添加一个test函数来验证邮箱唯一性——当存在重复邮箱时触发错误提示,请问如何在test函数中获取所有数组元素的值来做唯一性检查?

解决方案

1. 先修复Email字段的空值错误

你当前的Email校验逻辑存在冗余和提示错误的问题:test函数无论值是否为空都返回true,但后续的typeError却用了日期相关的提示文本。如果Email是可选字段,先调整基础校验逻辑:

Email: Yup.string()
  .email("Por favor, insira um email válido") // 可选:添加邮箱格式校验
  .typeError("Por favor, insira um email válido"),

如果需要Email为必填字段,在上述代码后追加.required("Este campo é obrigatório")即可。

2. 添加邮箱唯一性校验

Yup的test函数的校验回调可以接收第二个参数context,通过context.from[0].value能直接获取整个fileData数组,以此实现唯一性检查。具体代码如下:

Email: Yup.string()
  .email("Por favor, insira um email válido")
  .required("Este campo é obrigatório") // 可选:根据需求决定是否必填
  .test(
    "email-unique",
    "Este email já está sendo utilizado",
    (value, context) => {
      // 空值跳过校验(如果是必填字段,这里不会触发)
      if (!value) return true;
      // 获取整个fileData数组
      const allItems = context.from[0].value;
      // 统计当前邮箱在数组中的出现次数
      const duplicateCount = allItems.filter(item => item.Email === value).length;
      // 出现次数≤1则校验通过
      return duplicateCount <= 1;
    }
  )
  .typeError("Por favor, insira um email válido"),

关键说明

  • context.from[0].value:from是Yup内部的路径数组,第一个元素对应最外层的fileData字段,value就是该数组的当前完整值。
  • 若不需要邮箱格式校验,可以去掉.email()这一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:20:38