使用Zod解析器与react-hook-form验证分号分隔邮箱
验证分号分隔的邮箱地址(Zod)
问题背景
需要验证分号分隔的邮箱地址,要求不能使用.regex()方法,尝试用.refine()实现但代码无效。
原有无效代码:
const customSchema = z.object({factoryEmail: z.string().email()});
尝试过的无效写法:
const customSchema = z.object({factoryEmail: z.string().email().refine((emailValue) => emailValue.split(';').map(function(item) {customSchema.parse(item)}));}
解决方案
你的代码存在几个关键问题:
- 先调用
.email()会强制验证整个字符串是单个邮箱,直接阻断了多邮箱的验证逻辑,必须去掉这一步。 - 用
customSchema.parse(item)会导致循环引用(定义schema时还未完成就调用它),而且.map()仅做遍历,没有返回验证结果,应该用.every()确保所有项都合法。
正确的实现代码:
const customSchema = z.object({ factoryEmail: z.string().refine((value) => { // 按分号分割并去除每个邮箱前后的空格 const emailList = value.split(';').map(email => email.trim()); // 验证每一项都是合法邮箱 return emailList.every(email => z.string().email().safeParse(email).success); }, { message: "请输入分号分隔的有效邮箱地址" }) });
额外优化:解析为邮箱数组
如果需要把输入直接转换为干净的邮箱数组,可以配合.transform():
const customSchema = z.object({ factoryEmail: z.string() .refine((value) => { const emailList = value.split(';').map(email => email.trim()); return emailList.every(email => z.string().email().safeParse(email).success); }, { message: "请输入分号分隔的有效邮箱地址" }) .transform((value) => value.split(';').map(email => email.trim())) }); // 使用示例 const validInput = {factoryEmail: "playerone@gmail.com; playertwo@gmail.com"}; const parsedResult = customSchema.parse(validInput); // parsedResult.factoryEmail 输出:["playerone@gmail.com", "playertwo@gmail.com"]
内容的提问来源于stack exchange,提问作者Smeagol
相关产品推荐
相关产品推荐

