Условная валидация в Yup

У меня есть поле электронной почты, которое отображается только в том случае, если установлен флажок (логическое значение - true). Когда форма отправляется, я только то, что это поле нужно, если флажок установлен (boolean is true).

Это то, что я пробовал до сих пор:

    const validationSchema = yup.object().shape({
       email: yup
             .string()
             .email()
             .label('Email')
             .when('showEmail', {
                 is: true,
                 then: yup.string().required('Must enter email address'),
             }),
        })

Я пробовал несколько других вариантов, но я получаю ошибки от Formik и Yup:

Uncaught (in promise) TypeError: Cannot read property 'length' of undefined at yupToFormErrors (formik.es6.js:6198) at formik.es6.js:5933 at <anonymous> yupToFormErrors @formik.es6.js:6198

И я также получаю ошибки проверки от Yup. Что я делаю неправильно?

Ответ 1

Возможно, вы не определяете правило проверки для поля showEmail.

Я сделал CodeSandox, чтобы проверить это, и как только я добавил:

showEmail: yup.boolean()

Форма начала проверку корректно, и не было выдано никакой ошибки.

Это URL: https://codesandbox.io/s/74z4px0k8q

И на будущее это была правильная схема проверки:

validationSchema={yup.object().shape({
    showEmail: yup.boolean(),
    email: yup
      .string()
      .email()
      .when("showEmail", {
        is: true,
        then: yup.string().required("Must enter email address")
      })
  })
}

Ответ 2

Я сталкиваюсь с той же проблемой, но в моем случае

condition: when intakeDate values is {value: true, label: "Yes"}

billing_adress: Yup.string().when("intakeDate", {
   is: "true",
   then: Yup.string().required("This is a required field")
}),

@Lokuzt можешь дать мне какое-нибудь решение. Спасибо

Ответ 3

Полностью согласен с ответом @João Cunha. Просто дополнение к случаю использования радио кнопки.

Когда мы используем переключатель в качестве условия, мы можем проверить значение строки вместо логического. Например is: 'Phone'

const ValidationSchema = Yup.object().shape({
  // This is the radio button.
  preferredContact: Yup.string()
    .required('Preferred contact is required.'),
  // This is the input field.
  contactPhone: Yup.string()
    .when('preferredContact', {
      is: 'Phone',
      then: Yup.string()
        .required('Phone number is required.'),
    }),
  // This is another input field.
  contactEmail: Yup.string()
    .when('preferredContact', {
      is: 'Email',
      then: Yup.string()
        .email('Please use a valid email address.')
        .required('Email address is required.'),
    }),

});

Этот переключатель, записанный в ReactJS, метод onChange является ключом для запуска проверки состояния.

<label>
  <input
    name="preferredContact" type="radio" value="Email"
    checked={this.state.preferredContact == 'Email'}
    onChange={() => this.handleRadioButtonChange('Email', setFieldValue)}
  />
  Email
</label>
<label>
  <input
    name="preferredContact" type="radio" value="Phone"
    checked={this.state.preferredContact == 'Phone'}
    onChange={() => this.handleRadioButtonChange('Phone', setFieldValue)}
  />
  Phone
</label>

А вот функция обратного вызова при переключении переключателя. если мы используем Formik, setFieldValue - путь.

handleRadioButtonChange(value, setFieldValue) {
  this.setState({'preferredContact': value});
  setFieldValue('preferredContact', value);
}