[英]React validate password and confirm password fields
我试图验证值password
和confirmPassword
如下字段。 问题是状态更新似乎滞后了一个事件(字符)。 例如:如果 password.value = "pass1234",验证时的 confirmPassword.value 是 "pass123",尽管已经输入了 "4"。 所以验证发生在状态更新之前。 解决这个问题的最佳方法是什么?
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
import Aux from "../../hoc/Aux/Aux";
import Button from "../../components/UI/Button/Button";
import Input from "../../components/UI/Input/Input";
import Spinner from "../../components/UI/Spinner/Spinner";
import classes from "./Auth.module.css";
import * as actions from "../../store/actions/index";
class Auth extends Component {
state = {
controls: {
name: {
elementType: "input",
elementConfig: {
placeholder: "name"
},
value: "",
validation: {
required: true,
minLength: 4
},
valid: false,
touched: false
},
email: {
elementType: "input",
elementConfig: {
type: "email",
placeholder: "Email ID"
},
value: "",
validation: {
required: true,
isEmail: true
},
valid: false,
touched: false
},
password: {
elementType: "input",
elementConfig: {
type: "password",
placeholder: "password"
},
value: "",
validation: {
required: true,
minLength: 8
},
valid: false,
touched: false
},
confirmPassword: {
elementType: "input",
elementConfig: {
type: "password",
placeholder: "confirm password"
},
value: "",
validation: {
required: true,
minLength: 8,
passwordMatch: true
},
valid: false,
touched: false
}
},
isSignup: false
};
checkValidity(value, rules) {
let isValid = true;
if (!rules) {
return true;
}
if (rules.required) {
isValid = value.trim() !== "" && isValid;
}
if (rules.minLength) {
isValid = value.length >= rules.minLength && isValid;
}
if (rules.maxLength) {
isValid = value.length <= rules.maxLength && isValid;
}
if (rules.isEmail) {
const pattern = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
isValid = pattern.test(value) && isValid;
}
if (rules.isNumeric) {
const pattern = /^\d+$/;
isValid = pattern.test(value) && isValid;
}
if (rules.passwordMatch) {
const pwd = this.state.controls.password.value;
console.log("pwd: " + pwd);
console.log("pwdConfirm: " + this.state.controls.confirmPassword.value);
isValid = this.state.controls.confirmPassword.value === pwd;
}
return isValid;
}
inputChangedHandler = (event, controlName) => {
let updatedControls = {
...this.state.controls,
[controlName]: {
...this.state.controls[controlName],
value: event.target.value,
valid: this.checkValidity(
event.target.value,
this.state.controls[controlName].validation
),
touched: true
}
};
this.setState({ controls: updatedControls });
};
submitHandler = event => {
event.preventDefault();
if (!this.state.isSignup) {
this.props.onAuth(
this.state.controls.email.value,
this.state.controls.password.value,
this.state.isSignup
);
} else {
this.props.onSignUp(
this.state.controls.name.value,
this.state.controls.email.value,
this.state.controls.password.value,
this.state.controls.confirmPassword.value
);
}
};
switchAuthModeHandler = () => {
this.setState(prevState => {
return { isSignup: !prevState.isSignup };
});
};
render() {
const formElementsArray = [];
if (!this.state.isSignup) {
for (let key in this.state.controls) {
if (key !== "name" && key !== "confirmPassword") {
formElementsArray.push({
id: key,
config: this.state.controls[key]
});
}
}
} else {
for (let key in this.state.controls) {
formElementsArray.push({
id: key,
config: this.state.controls[key]
});
}
}
let form = null;
form = formElementsArray.map(formElement => (
<Input
key={formElement.id}
elementType={formElement.config.elementType}
elementConfig={formElement.config.elementConfig}
value={formElement.config.value}
invalid={!formElement.config.valid}
shouldValidate={formElement.config.validation}
touched={formElement.config.touched}
changed={event => this.inputChangedHandler(event, formElement.id)}
/>
));
let button;
if (!this.state.isSignup) {
button = <button btnType="Success">LOGIN</button>;
} else {
button = <button btnType="Success">REGISTER</button>;
}
let buttonRegister = null;
if (!this.state.isSignup) {
buttonRegister = (
<button btnType="SignUp" onClick={this.switchAuthModeHandler}>
SIGN UP FREE!
</button>
);
} else {
buttonRegister = (
<button btnType="SignUp" onClick={this.switchAuthModeHandler}>
Back to Login!
</button>
);
}
if (this.props.loading) {
form = <Spinner />;
}
let errorMessage = null;
if (this.props.error && !this.state.isSignup) {
errorMessage = <p>Email or Password is incorrect</p>;
}
if (this.props.error && this.state.isSignup) {
errorMessage = <p>Please confirm email is valid and passwords match</p>;
}
if (this.props.error && this.state.isSignup) {
let errorObj = JSON.parse(`${this.props.error}`);
if (errorObj.code == "11000") {
errorMessage = (
<p>
Email is already in use. Please reset your password, if you don't
remember it
</p>
);
}
}
let authRedirect = null;
if (this.props.isAuthenticated) {
authRedirect = <Redirect to={this.props.authRedirectPath} />;
}
return (
<div className={classes.Auth}>
{authRedirect}
{errorMessage}
<form onSubmit={this.submitHandler}>
{form}
{button}
</form>
{buttonRegister}
</div>
);
}
}
const mapStateToProps = state => {
return {
loading: state.auth.loading,
error: state.auth.error,
isAuthenticated: state.auth.token !== null,
role: state.auth.role,
userName: state.auth.name,
userPoints: state.auth.userPoints,
userJourneyPoints: state.auth.userJourneyPoints,
journeysCompleted: state.auth.journeysCompleted,
userLevel: state.auth.userLevel,
useHints: state.auth.useHints
};
};
const mapDispatchToProps = dispatch => {
return {
onAuth: (email, password, isSignup) =>
dispatch(actions.auth(email, password, isSignup)),
onSignUp: (name, email, password, confirmPassword) =>
dispatch(actions.signUp(name, email, password, confirmPassword))
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Auth);
浏览您的代码后,似乎您可以通过将target.event.value
与由于更改“确认密码”输入而调用inputChangedHandler
时password
的当前状态进行比较来解决问题。 您当前正在做的是在confirmPassword
有机会更新之前比较confirmPassword
和password
状态。 但是,“确认密码”输入的target.event.value
将在调用inputChangedHandler
时具有更新的值。
另一种解决方案可能是在componentDidUpdate
内验证您的表单,而不是在调用inputChangedHandler
立即验证。 通过在componentDidUpdate
内部进行验证,您可以确保状态有时间更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.