如何让Zod表单验证的双可选输入项均显示错误提示?
解决方法
问题出在Zod的refine方法上——你虽然在path里写了两个字段,但Zod并不会自动给两个字段都挂载错误,只会把错误绑定到数组的最后一个元素(也就是sampleb)上,这就是为啥只有它显示错误。
要让两个输入框都触发错误提示,推荐用superRefine来手动给不符合条件的字段加错误:
const schema = z.object({ samplea: z.string().optional(), sampleb: z.string().optional(), }).superRefine((args, ctx) => { // 判断是否只填了其中一个字段 const onlyOneFilled = (args.samplea && !args.sampleb) || (!args.samplea && args.sampleb); if (onlyOneFilled) { // 给samplea添加错误 ctx.addIssue({ code: z.ZodIssueCode.custom, message: "If you enter, please enter both", path: ["samplea"], }); // 给sampleb添加错误 ctx.addIssue({ code: z.ZodIssueCode.custom, message: "If you enter, please enter both", path: ["sampleb"], }); } });
这样改完之后,只要只填了其中一个字段,samplea和sampleb的错误对象都会被赋值,对应的输入框就能各自显示错误提示了。
你也可以用两次refine来分别检查每个字段,虽然代码有点重复,但错误提示可以更精准:
const schema = z.object({ samplea: z.string().optional(), sampleb: z.string().optional(), }) // 检查samplea填了的话,sampleb必须填 .refine(args => !args.samplea || args.sampleb, { message: "If you enter samplea, you must enter sampleb", path: ["samplea"], }) // 检查sampleb填了的话,samplea必须填 .refine(args => !args.sampleb || args.samplea, { message: "If you enter sampleb, you must enter samplea", path: ["sampleb"], });
你的表单组件代码不用改,保持原来的错误判断和提示逻辑就行。
内容的提问来源于stack exchange,提问作者otera
相关产品推荐
相关产品推荐

