Условная проверка на да

У меня есть поле электронной почты, которое отображается только в том случае, если установлен флажок (логическое значение - 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. Что я делаю неправильно?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
64
0
66 366
5

Ответы 5

Вероятно, вы не определяете правило проверки для поля 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")
      })
  })
}

Как это будет работать с тремя возможными значениями showEmail? Т.е. вместо логического () это была строка ()

DB1500 31.07.2019 23:41

Вы добавите конкретный тест к ключу is, используя функцию: is: (emailValue) => emailValue === "некоторая тестовая строка, которой вы хотите сопоставить"

Devin Clark 29.08.2019 20:56

Спасибо за ответ, я действительно понятия не имею, как вы пришли к этому решению, но это отражает серьезную проблему со многими пакетами npm, то есть 90 процентов документации библиотеки должно быть извлечено из вопросов Git или ответов SO.

mok 20.10.2019 03:29

Обновлены коды и ящик codeandbox.io/s/formik-conditional-val-1ldmx

Swar Shah 25.04.2020 20:09

Полностью согласен с ответом @ 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);
}

Автор формик тут ...

Чтобы Yup.when работал правильно, вам нужно добавить showEmail в initialValues и в форму схемы Yup.

В общем, при использовании validationSchema рекомендуется убедиться, что все поля вашей формы имеют начальные значения, чтобы Yup мог их сразу увидеть.

Результат будет выглядеть так:

<Formik 
  initialValues = {{ email: '', showEmail: false }}
  validationSchema = {Yup.object().shape({
    showEmail: Yup.boolean(),
    email: Yup
      .string()
      .email()
      .when("showEmail", {
        is: true,
        then: Yup.string().required("Must enter email address")
      })
  })
}

/>

Вы даже можете использовать функцию для сложных случаев. Функциональный регистр помогает при сложных проверках

validationSchema = {yup.object().shape({
    showEmail: yup.boolean(),
    email: yup
      .string()
      .email()
      .when("showEmail", (showEmail) => {
        if (showEmail)
          return yup.string().required("Must enter email address")
      })
  })
}
email: Yup.string()
    .when(['showEmail', 'anotherField'], {
        is: (showEmail, anotherField) => {
            return (showEmail && anotherField);
        },
        then: Yup.string().required('Must enter email address')
    }),

Другие вопросы по теме