将Yup验证错误转换为可用对象:Formik多Schema校验适配问题
解决Formik中Yup ValidationError转换为可用错误对象的问题
我有一个Formik表单,需要根据用户点击的提交按钮使用两种不同的校验Schema。不想用状态切换Schema,直接用Yup的validate方法校验后,得到的ValidationError无法直接传给Formik的setErrors方法,需要转换成以字段名为键、错误消息为值的对象。
原始代码问题
let validationErrors = null; try { // Validate the form data using a custom Schema await createDraftContractorFormValidationSchema.validate(values, { abortEarly: false, strict: false }); } catch (errors: any) { console.log(errors); // 需要把errors转成字段为键、消息为值的对象 if (errors) { formikRef.current.setErrors(errors); } }
控制台输出的错误信息:
ValidationError: 4 errors occurred at finishTestRun (runTests.js:54:1) at runTests.js:8:1 at finishTestRun (runTests.js:54:1) at runTests.js:8:1 at finishTestRun (runTests.js:54:1) at createValidation.js:60:1
解决方案
Yup的ValidationError对象包含一个inner属性,里面是所有字段错误的数组,每个元素都有path(字段名)和message(错误文本)。我们可以遍历这个数组,构建Formik需要的错误对象:
修改catch块的代码:
catch (errors: any) { if (errors instanceof Yup.ValidationError) { const formikErrors = errors.inner.reduce((acc, err) => { // 避免同一个字段的重复错误覆盖(如果有的话) if (!acc[err.path]) { acc[err.path] = err.message; } return acc; }, {} as Record<string, string>); formikRef.current.setErrors(formikErrors); } }
说明
- 首先判断捕获的错误是不是Yup的
ValidationError,避免处理其他类型的错误 - 用
reduce遍历errors.inner数组,把每个错误的path作为键,message作为值存入对象 - 加入判断避免同一个字段的错误被重复覆盖(如果Schema中同一个字段有多个校验规则,
abortEarly: false会返回多个错误,这里取第一个,也可以根据需求拼接所有消息)
内容的提问来源于stack exchange,提问作者Vuk
相关产品推荐
相关产品推荐

