我试图使用Formik和Yup显示错误消息,基于条件,如果用户名已经采取或不。我从我的nodejs后端得到响应,如果响应是假的用户名已经存在于数据库中,我需要显示一个错误"它已经采取"。验证模式:
const validationSchema = yup.object({
isTaken:yup.boolean(),
username: yup.string().when('isTaken',{
is:false,
then:yup.string().required('Username taken')
}),
password: yup.string().required('Required'),
confirmPassword: yup.string().required('Required').oneOf([yup.ref('password'), null], 'Passwords must match')
});
我正在尝试这种方式,但据我所知,这应该只工作,如果isTaken是表单内的值。我需要使用react state存储响应,并在Yup中使用它来呈现消息,但我很难这样做。
validationSchema
可以从以下函数返回
const makeConditionalSchema = (stateValue) => {
if (stateValue === someCondition) {
return yup.object({/* validation one */})
}
return yup.object({/* some other validation */})
}
和Formik中-
<Formik
validationSchema={makeConditionalSchema(stateValue)}
// other props
我解决这个问题的方法是在yup验证中进行异步api调用。是的,提供一个"测试",你可以这样使用。
username: yup
.string()
.required('username is required')
.test('checkIfTaken',
'user name is taken, try something else',
function (value) {
//if cur value is empty its not allowed
if (value === "") return true;
//make api call to check if username is taken
//using fetch etc. here we are just using timeout
//api example: fetch(`{baseURI}/checkDuplicate?username=${value}`).then(....)
return new Promise((resolve, reject) => {
const randomInt = generateRandomInt();
setTimeout(() => {
if (randomInt % 2 == 0) {
resolve(true);
} else {
resolve(false)
}
}, 1000);
})
}),