问题描述
我想在 React 中创建一个密码更改表单。这是我的组件的代码:
import React,{ Component } from "react";
import Joi from "joi-browser";
import "./Login/Login.css";
import { UAA } from "../../Actions/Types";
class ChangePassword extends Component {
state = {
account: {
currentPassword: "",newPassword: "",newPasswordRepeated: "",},errors: {},auth: UAA,};
schema = {
currentPassword: Joi.string().required().label("Password"),newPassword: Joi.string().min(12).max(64).required().label("Password"),newPasswordRepeated: Joi.any().valid(Joi.ref("newPassword")).required(),};
validate = () => {
const options = { abortEarly: false };
const { error } = Joi.validate(this.state.account,this.schema,options);
if (!error) return null;
const errors = {};
for (let item of error.details) {
errors[item.path[0]] = item.message;
}
return errors;
};
validateProperty = ({ name,value }) => {
const obj = { [name]: value };
console.log(obj);
const schema = { [name]: this.schema[name] };
console.log(schema);
const { error } = Joi.validate(obj,schema);
console.log(JSON.stringify(error));
return error ? error.details[0].message : null;
};
handleSubmit = (e) => {
e.preventDefault();
const errors = this.validate();
this.setState({ errors: errors || {} });
if (errors) return;
//todo : call server
};
handleChange = ({ currentTarget: input }) => {
const errors = { ...this.state.errors };
const errorMessage = this.validateProperty(input);
if (errorMessage) errors[input.name] = errorMessage;
else delete errors[input.name];
const account = { ...this.state.account };
account[input.name] = input.value;
this.setState({
account: account,errors: errors,});
};
render() {
const { errors,account } = this.state;
return (
<div className="container">
<div className="col-md-5 offset-md-3">
<form
className="login-form"
onSubmit={(event) => this.handleSubmit(event)}
>
<p />
<p className="form-label">Current password</p>
<input
type="password"
id="currentPassword"
name="currentPassword"
value={account.currentPassword}
onChange={this.handleChange}
/>
{errors.currentPassword && (
<div className="alert alert-danger">{errors.currentPassword}</div>
)}
<p className="form-label">New password</p>
<input
type="password"
name="newPassword"
onChange={this.handleChange}
value={account.newPassword}
/>
{errors.newPassword && (
<div className="alert alert-danger">{errors.newPassword}</div>
)}
<p className="form-label">Confirm password</p>
<input
type="password"
name="newPasswordRepeated"
value={account.newPasswordRepeated}
onChange={this.handleChange}
/>
{errors.newPasswordRepeated && (
<div className="alert alert-danger">
{errors.newPasswordRepeated}
</div>
)}
<div className="submit-login-form">
<input
type="submit"
value="Submit"
disabled={this.validate()}
></input>
</div>
</form>
</div>
</div>
);
}
}
export default ChangePassword;
当用户输入重复密码时,我想验证该重复密码是否与已输入的新密码匹配。这是在 validateProperty
方法中完成的。问题是 Joi 即使两个密码匹配也返回验证错误。我很感激这方面的任何帮助。
解决方法
经过一番研究,我能够找出问题所在。
问题在于验证字段 validateProperty
时使用的 Joi 架构中的方法 newPasswordRepeated
。在此模式中,需要为 newPassword
添加验证规则。因此,我更改了我的 validateProperty
方法,如下所示:
validateProperty = ({ name,value }) => {
if (name === "newPasswordRepeated") {
const { account } = this.state;
const obj = { newPassword: account.newPassword,[name]: value };
const schema = {
[name]: this.schema[name],newPassword: 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;
}
};
希望有人觉得这有用。