我有一个电子邮件字段,仅在选中复选框时才会显示(布尔值为
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 收到验证错误。我做错了什么?
您可能没有为 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")
})
})
}
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")
})
})
}
/>
您甚至可以使用函数来处理复杂的情况。功能案例有助于复杂的验证
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
})
})
}
完全同意@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);
}
email: Yup.string()
.when(['showEmail', 'anotherField'], {
is: (showEmail, anotherField) => {
return (showEmail && anotherField);
},
then: Yup.string().required('Must enter email address')
}),
它对我来说非常有效:
Yup.object().shape({
voyageStartDate:Yup.date(),
voyageEndDate:Yup.date()
.when(
'voyageStartDate',
(voyageStartDate, schema) => (moment(voyageStartDate).isValid() ? schema.min(voyageStartDate) : schema),
),
})
使用 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 } });
这是项目的示例代码
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
}
不使用函数符号检查特定值:
如果选择
choice
有值date
,则需要输入字段date
:
availableDate: yup.string().when('choice', {
is: (v) => v === 'date',
then: (schema) => schema.required('date is required')
})
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,
});
}
};
对于使用此的打字稿 ✅
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")
}),