如何在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
相关产品推荐
相关产品推荐

