【问题标题】:Async validation with Formik, Yup and React使用 Formik、Yup 和 React 进行异步验证
【发布时间】:2019-09-12 15:11:29
【问题描述】:

我想使用 formik 进行异步验证,使用 yup 进行验证模式,但我找不到示例或演示。

【问题讨论】:

    标签: reactjs formik yup


    【解决方案1】:
    const validationSchema = Yup.object().shape({
        username:
            Yup.string()
                .test('checkDuplUsername', 'same name exists', function (value) {
                    return new Promise((resolve, reject) => {
                        kn.http({
                            url: `/v1/users/${value}`,
                            method: 'head',
                        }).then(() => {
                            // exists
                            resolve(false)
                        }).catch(() => {
                            // note exists
                            resolve(true)
                        })
                    })
                })
    })
    

    是的,通过测试方法提供异步处理。
    (kn 是我的 ajax 承诺函数)
    祝你有美好的一天。

    【讨论】:

    • 知道如何对同一个字段进行多次验证吗?例如,如果名称是必需的,并且必须是唯一的
    • @tsinat 简单地链接它 - 例如,Yup.string.required('Username is required').test(...)
    • 这样做会给我带来以下结果:Error: Validation test of type: "exists" returned a Promise during a synchronous validate. This test will finish after the validate call has returned
    • 您还需要返回 kn.http 否则您将失去异步链
    【解决方案2】:

    其实可以简化一点

    
    const validationSchema = Yup.object().shape({
        username: Yup.string().test('checkEmailUnique', 'This email is already registered.', value =>
            fetch(`is-email-unique/${email}`).then(async res => {
                const { isEmailUnique } = await res.json()
    
                return isEmailUnique
            }),
        ),
    })
    

    【讨论】:

      【解决方案3】:

      以下是如何通过 API 调用进行异步验证:

      const validationSchema = Yup.object().shape({
        username: Yup.string().test('checkDuplUsername', 'same name exists', function (value) {
          if (!value) {
            const isDuplicateExists = await checkDuplicate(value);
            console.log("isDuplicateExists = ", isDuplicateExists);
            return !isDuplicateExists;
          }
          // WHEN THE VALUE IS EMPTY RETURN `true` by default
          return true;
        }),
      });
      
      function checkDuplicate(valueToCheck) {
        return new Promise(async (resolve, reject) => {
          let isDuplicateExists;
      
          // EXECUTE THE API CALL TO CHECK FOR DUPLICATE VALUE
          api.post('url', valueToCheck)
          .then((valueFromAPIResponse) => {
            isDuplicateExists = valueFromAPIResponse; // boolean: true or false
            resolve(isDuplicateExists);
          })
          .catch(() => {
            isDuplicateExists = false;
            resolve(isDuplicateExists);
          })
        });
      }
      

      【讨论】:

        【解决方案4】:

        比如我用的是假promise,可以这样做:

          const Schema = yup.object().shape({
              password: yup
           .string()
          .test("validPassword","Password requires one special character",
          function (value) {
            return new Promise((resolve) => {
              setTimeout(() => {
                if (
                  /^[0-9A-Za-z]*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?][0-9a-zA-Z]*$/.test(
                    value
                  )
                ) {
                  resolve(true);
                } else {
                  resolve(false);
                }
              }, 100);
            });
          }
         ),
        });
            
        

        【讨论】:

          【解决方案5】:

          您可以将async/awaityup 自定义验证器一起使用

          let field = yup.string().test(
          'test-id',
          'error message in case of fail',
           async function validateValue(value){
            try{
              
               // validation logic
               return false; // or true as you see fit
          
            } catch(error){
          
            }
          });
          

          为您接受的值返回true

          为您拒绝的值返回false

          确保您始终返回一个布尔值,或者如果您自己无法保证,请添加一个 finally 块。

          【讨论】:

            猜你喜欢
            • 2019-12-26
            • 2019-10-09
            • 1970-01-01
            • 2020-01-01
            • 2021-06-27
            • 2020-07-05
            • 2020-12-06
            • 1970-01-01
            • 2019-09-29
            相关资源
            最近更新 更多