Javascript 是的条件验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49394391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:22:06  来源:igfitidea点击:

Conditional Validation in Yup

javascriptreactjsyupformik

提问by reectrix

I have an email field that only gets shown if a checkbox is selected (boolean value is true). When the form get submitted, I only what this field to be required if the checkbox is checked (boolean is true).

我有一个电子邮件字段,只有在选中复选框时才会显示(布尔值为true)。当表单被提交时,如果复选框被选中(布尔值为真),我只需要这个字段。

This is what I've tried so far:

这是我迄今为止尝试过的:

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

I've tried several other variations, but I get errors from Formik and Yup:

我尝试了其他几种变体,但我从 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

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

And I get validation errors from Yup as well. What am I doing wrong?

我也从 Yup 那里收到验证错误。我究竟做错了什么?

回答by Jo?o Cunha

You probably aren't defining a validation rule for the showEmailfield.

您可能没有为showEmail字段定义验证规则。

I've done a CodeSandox to test it out and as soon as I added:

我已经做了一个 CodeSandox 来测试它,并在我添加后立即:

showEmail: yup.boolean()

The form started validation correctly and no error was thrown.

表单正确开始验证并且没有抛出错误。

This is the url: https://codesandbox.io/s/74z4px0k8q

这是网址:https: //codesandbox.io/s/74z4px0k8q

And for future this was the correct validation schema:

对于未来,这是正确的验证模式:

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

回答by Eric Tan

Totally agree with @Jo?o Cunha's answer. Just a supplement for the use case of Radio button.

完全同意@Jo?o Cunha 的回答。只是对 Radio 按钮用例的补充。

When we use radio button as condition, we can check value of string instead of boolean. e.g. is: 'Phone'

当我们使用单选按钮作为条件时,我们可以检查字符串的值而不是布尔值。例如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.'),
    }),

});

This the radio button written in ReactJS, onChange method is the key to trigger the condition checking.

这个用 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>

And here's the callback function when radio button get changed. if we are using Formik, setFieldValueis the way to go.

这是单选按钮更改时的回调函数。如果我们使用 Formik,setFieldValue是要走的路。

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