我在React中使用joi-browser
进行表单验证。我面临的问题是在输入上验证password
和confirmPassword
。
我使用的模式与另一个stackoverflow问题中提供的模式相同。
password: Joi.string().min(3).max(15).required(),
confirmPassword: Joi.any().valid(Joi.ref('password')).required().options({ language: { any: { allowOnly: 'must match password' } } })
一旦我开始输入confirmPassword
,即使它和password
一样,我的错误也会出现,在提交时它会消失并提交表单。但如果confirmPassword
不一样,它就无法提交,这没关系。
我想要的是,它应该在onChange
事件上进行验证,如果confirmPassword
字段与password
字段匹配,则必须删除错误。
代码逻辑是,所有字段都在状态中的formData
中定义,所有错误都将存储在state.errors
中同名的errors
对象中。若出现错误,它将在errors对象中创建条目,否则将其从errors对象删除。
我的表单状态为:
state = {
formData: {
password: '',
confirmPassword: ''
},
errors: {}
}
on更改方法为:
onChangeField = ({ currentTarget: input }) => {
const errors = { ...this.state.errors };
const errorMsg = this.validateField(input);
if (errorMsg) errors[input.name] = errorMsg;
else delete errors[input.name];
const formData = { ...this.state.formData };
formData[input.name] = input.value;
this.setState({ formData, errors });
}
validateField = ({ name, value }) => {
const obj = { [name]: value };
const schema = { [name]: this.schema[name] };
const { error } = Joi.validate(obj, schema);
return error ? error.details[0].message : null;
};
我也面临同样的问题。这一切都是因为异步和等待模式。如果您将日志记录添加到案例中,您会看到它并没有在ChangeField上设置状态。例如,它正在进行异步操作。我还没有找到最好的情况,但如果你添加一个完整的验证并等待状态设置,它就会起作用。
例如,我添加了以下内容:
onChangeField = async ({ currentTarget: input }) => {
const errors = { ...this.state.errors };
const errorMsg = this.validateField(input);
if (errorMsg) errors[input.name] = errorMsg;
else delete errors[input.name];
const formData = { ...this.state.formData };
formData[input.name] = input.value;
await this.setState({ data, errors });
if(!this.validate()){
console.log(true);
this.setState({ errors: {} });
}
}
问题出现在validateField
方法中,特别是在验证字段confirmPassword
时使用的Join模式中。在这个模式中,还需要为password
字段添加一个验证规则。所以你需要把validateField
方法改成这样:
validateField = ({ name, value }) => {
if (name === "confirmPassword") {
const { formData} = this.state;
const obj = { password: formData.password, [name]: value };
const schema = {
[name]: this.schema[name],
password: this.schema["newPassword"],
};
const { error } = Joi.validate(obj, schema);
return error ? error.details[0].message : null;
}else{
const obj = { [name]: value };
const schema = { [name]: this.schema[name] };
const { error } = Joi.validate(obj, schema);
return error ? error.details[0].message : null;
}
};