简体   繁体   中英

Conditional validation with Yup and Formik

Here is my validation schema:

const validationSchema = Yup.object().shape({
      person: Yup.object().shape({
        name: Yup.string().required('Field is required'),
        surname: Yup.string().required('Field is required'),
        middleName: Yup.string().required('Field is required'),
        email: Yup.string()
          .email('Wrong e-mail format')
          .required('Field is required')
      }),
      company: Yup.object().shape({
        name: Yup.string().required('Field is required'),
        address: Yup.string().required('Field is required'),
        email: Yup.string()
          .email('Wrong e-mail format')
          .required('Field is required')
      })
    });

And also there are two variables in React State: isPerson and isCompany . How to make validation work conditionally, for example if isPerson is true, then person in validationSchema is required to be validated?

Updated ans: 2020.

you can use Yup conditions

const validationSchema = Yup.object().shape({

      isCompany: Yup.boolean(),
      companyName: Yup.string().when('isCompany', {
        is: true,
        then: Yup.string().required('Field is required')
      }),
      companyAddress: Yup.string().when('isCompany', {
        is: (isCompany) => true,//just an e.g. you can return a function
        then: Yup.string().required('Field is required'),
        otherwise: Yup.string()
      }),
    });


And make sure to update your form accordingly. I hope you get the point...

You can conditionally add to your validation schema just like any other object:

let validationShape = {
  company: Yup.object().shape({
    name: Yup.string().required('Field is required'),
    address: Yup.string().required('Field is required'),
    email: Yup.string()
      .email('Wrong e-mail format')
      .required('Field is required')
  })
};

if (this.state.isPerson) {
  validationShape.person = Yup.object().shape({
    name: Yup.string().required('Field is required'),
    surname: Yup.string().required('Field is required'),
    middleName: Yup.string().required('Field is required'),
    email: Yup.string()
      .email('Wrong e-mail format')
      .required('Field is required');
}

const validationSchema = Yup.object().shape(validationShape);
                email: Yup.string()
                    .when([‘, 'showEmail’, ’anotherField’], {
                        is: (showEmail, anotherField) => {
                            return (showEmail && anotherField);
                        },
                        then: Yup.string().required('Must enter email address')
                    }),

Multiple fields can also be used for validation.

While the accepted solution works, it had one problem - two of the fields to be validated were common, and had to be duplicated. In my case, I had majority of the fields common with just 2-4 outliers.

So here is another solution:

  1. Define each schema separately - ie 3 schemas - commonSchema for the common fields, personSchema for person specfic fields & companySchema for company specific fields.

  2. Merge the schemas based on the state

     const validationSchema = isPerson ? commonSchema.concat(personSchema) : commonSchema.contact(companySchema)

For details on 'concat', refer to the yup docs on github.

Conditional validations with YUP :

All kinds of validation that can be done with when are as follows:

1. Single value, simple condition :
RULE: Only ask for personName when isPerson true.

personName : string().when('isPerson', {
is: true, 
then: Yup.string().required('Field is required'),
otherwise: Yup.string(),
})

2. Single value, complex condition :
RULE: Only ask for personName when company is "IT".


personName : string().when('company', {
is: (company)=> company==='IT', 
then: Yup.string().required('Field is required'),
otherwise: Yup.string(),
})

2. Multi value, complex condition :
RULE: Only ask for personName when company is "IT" and person is valid.


personName : string().when(['company', 'isPerson'], {
is: (company,isPerson)=> company==='IT'&& isPerson, 
then: Yup.string().required('Field is required'),
otherwise: Yup.string(),
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM