Search code examples
javascriptreactjsyup

Conditional yup validation based on state


I have this validation:

    ticket: yup
      .number()
      .required(I18n.t("is_required"))
      .when([], {
        is: () => {
          return timeFramedExperience;
        },
        then: yup.number().nullable(),
      }),
    max_p: yup
      .number()
      .required(I18n.t("is_required"))
      .when([], {
        is: () => {
          return timeFramed;
        },
        then: yup.number().nullable(),
      }),

timeFramed is a react hook state set to true. I want these fields, max_p and ticket to not be required when timeFramed is true.

but, on submit, I get this error:

Cannot read properties of undefined (reading 'reduce')

Solution

    1. Use different schemas as OP mentioned:
       condition ? : schema1 : schema2
    
    1. Use yup context:
       yup
       .string()
       .when("$condition", (condition, schema) =>
         condition ? schema : schema.required()
         // Here `condition` is passed as context to yup.
       )
    
    1. Use a hidden field or add the state to the form somehow.

    I created a codesandbox which uses react-hook-form and yup to validate and has implemented the 3 solutions mentioned above.

    If your state may change during the time user is filling in the form, be careful about calling trigger. Calling trigger before your state updates in the next render could lead to bugs.