使用Formik,Yup和React进行异步验证

时间:2019-04-23 12:20:14

标签: reactjs formik yup

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

5 个答案:

答案 0 :(得分:2)

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)
                    })
                })
            })
})

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

答案 1 :(得分:0)

同步和异步验证

    // Synchronous validation
const validate = (values, props /* only available when using withFormik */) => {
  let errors = {};

  if (!values.email) {
    errors.email = 'Required';
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = 'Invalid email address';
  }

  //...

  return errors;
};

// Async Validation
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const validate = (values, props /* only available when using withFormik */) => {
  return sleep(2000).then(() => {
    let errors = {};
    if (['admin', 'null', 'god'].includes(values.username)) {
      errors.username = 'Nice try';
    }
    // ...
    if (Object.keys(errors).length) {
      throw errors;
    }
  });
};

YUP验证架构

import React from 'react';
import { Formik, Form, Field } from 'formik';
import * as Yup from 'yup';

const SignupSchema = Yup.object().shape({
  firstName: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  lastName: Yup.string()
    .min(2, 'Too Short!')
    .max(50, 'Too Long!')
    .required('Required'),
  email: Yup.string()
    .email('Invalid email')
    .required('Required'),
});

export const ValidationSchemaExample = () => (
  <div>
    <h1>Signup</h1>
    <Formik
      initialValues={{
        firstName: '',
        lastName: '',
        email: '',
      }}
      validationSchema={SignupSchema}
      onSubmit={values => {
        // same shape as initial values
        console.log(values);
      }}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="firstName" />
          {errors.firstName && touched.firstName ? (
            <div>{errors.firstName}</div>
          ) : null}
          <Field name="lastName" />
          {errors.lastName && touched.lastName ? (
            <div>{errors.lastName}</div>
          ) : null}
          <Field name="email" type="email" />
          {errors.email && touched.email ? <div>{errors.email}</div> : null}
          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);

参考:https://jaredpalmer.com/formik/docs/guides/validation

答案 2 :(得分:0)

实际上,它可以简化一点


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 :(得分:0)

以下是通过 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 :(得分:0)

例如我使用的是假承诺,可以按如下方式完成:

  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);
    });
  }
 ),
});