如何在YUP异步验证中设置动态错误消息?

人气:358 发布:2023-01-03 标签: reactjs formik yup

问题描述

我正在尝试使用Yup的.test()方法在Formik中进行异步验证,并且需要设置从API获得的错误消息。根据后端的某些情况,错误消息会有所不同。

尝试了这里提到的几种解决方案 https://github.com/jquense/yup/issues/222和Dynamic Validation Messages Using Yup and Typescript

但Yup正在抛出test()中给出的默认错误消息。

文档显示

所有测试都必须提供名称、错误消息和必须返回TRUE或FALSE或ValidationError的验证函数。若要使测试异步返回解决True或False的承诺或ValidationError,请执行以下操作。

我正在使用错误消息解析新的ValidationError,但它仍然引发默认错误。

以下是代码。

const schema = Yup.object().shape({
  email: Yup.string().test(
    "email_async_validation",
    "Email Validation Error", // YUP always throws this error
    value => {
      return new Promise((resolve, reject) => {
        emailValidationApi(value)
          .then(res => {
            const { message } = res.data; // I want this error message to be shown in form.
            resolve(new Yup.ValidationError(message));
          })
          .catch(e => {
            console.log(e);
          });
      });
    }
  )
});

推荐答案

我使用function语法而不是验证函数的箭头函数使其正常工作。

医生说:

使用特殊的上下文或this值调用测试函数, 公开了一些有用的元数据和函数。请注意,要使用this 上下文中,测试函数必须是函数表达式,而不是箭头函数,因为箭头函数具有 词汇上下文。

以下是工作代码。

const schema = Yup.object().shape({
  email: Yup.string()
    .email("Not a valid email")
    .required("Required")
    .test("email_async_validation", "Email Validation Error", function (value) { // Use function
      return emailValidationApi(value)
        .then((res) => {
          const message = res;
          console.log("API Response:", message);
          return this.createError({ message: message });
          // return Promise.resolve(this.createError({ message: message })); // This also works
        })
        .catch((e) => {
          console.log(e);
        });
    })
});

28