Yup中的条件验证

ree*_*rix 19 javascript reactjs yup formik

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

这是我到目前为止所尝试的:

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

我尝试过其他几种变体,但是我从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那里得到验证错误.我究竟做错了什么?

小智 40

Formik 作者在这里...

为了使Yup.when正常工作,你必须添加showEmailinitialValues和你是的模式形状。

通常,在使用 时validationSchema,最佳做法是确保所有表单字段都具有初始值,以便您可以立即看到它们。

结果将如下所示:

<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")
      })
  })
}

/>
Run Code Online (Sandbox Code Playgroud)

  • “确保所有表单字段都有初始值的最佳实践......”一个很常见的例子是数字输入,但这种情况并不成立。假设您希望输入从空开始。不与零,不与任何其他数字。您必须将此字段初始化为未定义。 (14认同)

Joã*_*nha 30

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

我做了一个CodeSandox来测试它,并在我添加时:

showEmail: yup.boolean()
Run Code Online (Sandbox Code Playgroud)

表单正确启动验证并且没有抛出错误.

这是网址: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")
      })
  })
}
Run Code Online (Sandbox Code Playgroud)

  • 对于 showEmail 的三个可能值,这将如何工作?即,它不是 boolean(),而是 string() (4认同)
  • 您将使用函数向 is 键添加特定测试: is: (emailValue) =&gt; emailValue === "some test string you want it to match" (2认同)
  • 更新了codesandbox https://codesandbox.io/s/formik-conditional-val-1ldmx (2认同)
  • 在新的 yup `v1` 和更高版本中,您必须在执行条件时返回 schema,如下所示 `then: (schema) =&gt; schema.min(5)...` (2认同)

par*_*shm 19

email: Yup.string()
    .when(['showEmail', 'anotherField'], {
        is: (showEmail, anotherField) => {
            return (showEmail && anotherField);
        },
        then: Yup.string().required('Must enter email address')
    }),
Run Code Online (Sandbox Code Playgroud)


Geo*_*ich 8

使用 Yupv1和 Upper 的任何人请注意。v1.2就我而言。根据官方文档,你必须(schema) => ...在你的条件下做

官方文档:
对于具有动态组件(引用、惰性或条件)的模式,描述需要更多上下文才能准确返回模式描述。在这些情况下提供选项

import { ref, object, string, boolean } from 'yup';

let schema = object({
  isBig: boolean(),
  count: number().when('isBig', {
    is: true,
    then: (schema) => schema.min(5),
    otherwise: (schema) => schema.min(0),
  }),
});

schema.describe({ value: { isBig: true } });
Run Code Online (Sandbox Code Playgroud)


Eri*_*Tan 6

完全同意@JoãoCunha的回答。只是单选按钮用例的补充。

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

});
Run Code Online (Sandbox Code Playgroud)

这是用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>
Run Code Online (Sandbox Code Playgroud)

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

handleRadioButtonChange(value, setFieldValue) {
  this.setState({'preferredContact': value});
  setFieldValue('preferredContact', value);
}
Run Code Online (Sandbox Code Playgroud)


sri*_*r.. 6

您甚至可以将函数用于复杂情况。函数案例有助于复杂的验证

validationSchema={yup.object().shape({
    showEmail: yup.boolean(),
    email: yup
      .string()
      .email()
      .when("showEmail", (showEmail) => {
        if(showEmail)
          return yup.string().required("Must enter email address")
      })
  })
}
Run Code Online (Sandbox Code Playgroud)