是的条件验证

问题描述 投票:0回答:11

我有一个电子邮件字段,仅在选中复选框时才会显示(布尔值为

true
)。当表单提交时,如果选中复选框(布尔值为 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 收到验证错误。我做错了什么?

javascript reactjs yup formik
11个回答
194
投票

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

我已经做了一个 CodeSandox 来测试它,一旦我添加:

showEmail: yup.boolean()

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

这是网址: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")
      })
  })
}

82
投票

Formik 作者在这里...

要使

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

/>

35
投票

您甚至可以使用函数来处理复杂的情况。功能案例有助于复杂的验证

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

25
投票

完全同意@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);
}

19
投票
email: Yup.string()
    .when(['showEmail', 'anotherField'], {
        is: (showEmail, anotherField) => {
            return (showEmail && anotherField);
        },
        then: Yup.string().required('Must enter email address')
    }),

3
投票

它对我来说非常有效:

   Yup.object().shape({
    voyageStartDate:Yup.date(),
    voyageEndDate:Yup.date()
        .when(
            'voyageStartDate',
            (voyageStartDate, schema) => (moment(voyageStartDate).isValid() ? schema.min(voyageStartDate) : schema),
        ),
})

3
投票

使用 Yup

v1
及以上的任何人请注意。
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 } });

1
投票

我将 yup 与 vee-validate 一起使用

vee 验证

这是项目的示例代码

const schema = yup.object({
    first_name: yup.string().required().max(45).label('Name'),
    last_name: yup.string().required().max(45).label('Last name'),
    email: yup.string().email().required().max(255).label('Email'),
    self_user: yup.boolean(),
    company_id: yup.number()
        .when('self_user', {
            is: false,
            then: yup.number().required()
        })
})
const { validate, resetForm } = useForm({
    validationSchema: schema,
    initialValues: {
        self_user: true
    }
})

const {
    value: self_user
} = useField('self_user')
const handleSelfUserChange = () => {
    self_user.value = !self_user.value
}

1
投票

不使用函数符号检查特定值:

如果选择

choice
有值
date
,则需要输入字段
date

availableDate: yup.string().when('choice', {
    is: (v) => v === 'date',
    then: (schema) => schema.required('date is required')
})

0
投票
This Code Works For ME Try To use It

const validation = () => {
   try {
    let userSchema = Yup.object().shape({
    date: Yup.string().required(),
    city: Yup.string().required(),
    gender: Yup.string().required(),
    email: Yup.string()
      .matches(
        /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|. 
   (".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA- 
   Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
      )
      .nullable(true),
    userName: Yup.string().min(3),
  });
  userSchema.validateSync({
    email: email,
    userName: userName,
    gender: gender.name,
    city: city.name,
    date: date,
   });
 } catch (error) {
  console.log(error);
   setError({
     userName: '',
     email: '',
     gender: '',
     city: '',
     date: '',
     [error.path]: error.name,
    });
   }
 };

0
投票

对于使用此的打字稿 ✅

reasonContractNotDone: yup.string().when('isContractDone', {
  is: false,
  then(schema) {
    return schema.required('Must enter email address');
  },
}),

不像下面这样! ⛔

reasonContractNotDone: yup.string().when('isContractDone', {
  is: false,
  then: yup.string().required("Must enter email address")
}),
© www.soinside.com 2019 - 2024. All rights reserved.