admin管理员组

文章数量:1316674

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

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')
Share Improve this question edited Nov 10, 2022 at 16:28 c0m1t 1,2421 gold badge9 silver badges18 bronze badges asked Nov 10, 2022 at 13:50 GoteyGotey 6396 gold badges19 silver badges48 bronze badges 6
  • Possibly duplicate of this or this. – c0m1t Commented Nov 10, 2022 at 14:02
  • in my case I want to use a react hook state to decide on the condition, not a form registered field – Gotey Commented Nov 10, 2022 at 15:16
  • 1 In that case you could add the state as a field, or use yup context. Here is an example that might help you. See yup documentation. – c0m1t Commented Nov 10, 2022 at 15:44
  • I'll check that. I was able to solve it creating two schemas and concatenating them based on that condition – Gotey Commented Nov 10, 2022 at 16:00
  • @c0m1t Incorrect. Your references are questions on conditionals using other form fields. As the OP suggested, (and what I'm also trying to achieve) is conditionals based on outside variables, such as state. – anastymous Commented May 8, 2023 at 22:15
 |  Show 1 more ment

2 Answers 2

Reset to default 7
  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.

In addition to the answers here, you can expand a schema based on a condition like so:

const createSchema = (condition) => {
  // Base schema
  const schema = yup.string()...etc

  // Expand based on condition
  return condition ? schema.required('required field') : schema
}

本文标签: javascriptConditional yup validation based on stateStack Overflow