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

将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:24:22