当我尝试使用useReducer作为状态管理时,当我使用onChange和reducer时出现了一个问题,这是一个字符延迟。有一个useEffect依赖于字符的变化来将有效性值设置为true或false。
但是它和onBlur配合得很好。
延误的原因是什么?
我该如何解决这个问题?
import React, { useState, useEffect, useReducer, useContext } from "react";
import AuthContext from "../store/auth-context";
import Button from "../UI/Button";
import Card from "../UI/Card";
import Input from "../UI/Input";
const reducerFn = (state, action) => {
if (action.type === "Email") {
return {
...state,
emailState: action.value,
};
} else if (action.type === "Email_IsValid") {
return {
...state,
isEmailValid: true,
};
} else if (action.type === "Email_IsInValid") {
return {
...state,
isEmailValid: false,
};
} else if (action.type === "Password") {
return {
...state,
passwordState: action.value,
};
} else if (action.type === "Password_IsValid") {
return {
...state,
isPasswordIsValid: true,
};
} else if (action.type === "Password_IsInValid") {
return {
...state,
isPasswordIsValid: false,
};
}
return { emailState: "", isEmailValid: false, passwordState: "", isPasswordIsValid: false };
};
const Login = () => {
const [formState, dispatchFn] = useReducer(reducerFn, { emailState: "", isEmailValid: false, passwordState: "", isPasswordIsValid: false });
const { emailState, isEmailValid, passwordState, isPasswordIsValid } = formState;
const [isEmailValidated, setIsEmailValidated] = useState(null);
const [isPasswordIsValidated, setIsPasswordIsValidated] = useState(null);
const authCtx = useContext(AuthContext);
useEffect(() => {
if (isEmailValid) setIsEmailValidated(true);
if (isPasswordIsValid) setIsPasswordIsValidated(true);
}, [isEmailValid, isPasswordIsValid]);
const onEmailChangeHandler = ({ target }) => {
console.log(isEmailValid, isEmailValidated);
dispatchFn({ type: "Email", value: target.value });
if (emailState.includes("@")) {
dispatchFn({ type: "Email_IsValid" });
} else {
dispatchFn({ type: "Email_IsInValid" });
setIsEmailValidated(false);
}
};
const onEmailBlurHandler = () => {
if (emailState.includes("@")) {
dispatchFn({ type: "Email_IsValid" });
} else {
dispatchFn({ type: "Email_IsInValid" });
setIsEmailValidated(false);
}
};
const onPasswordChangeHandler = ({ target }) => {
dispatchFn({ type: "Password", value: target.value });
if (passwordState.length > 7) {
dispatchFn({ type: "Password_IsValid" });
} else {
dispatchFn({ type: "Password_IsInValid" });
setIsPasswordIsValidated(false);
}
console.log(isPasswordIsValid);
};
const onPasswordBlurHandler = () => {
if (passwordState.length > 7) {
dispatchFn({ type: "Password_IsValid" });
} else {
dispatchFn({ type: "Password_IsInValid" });
setIsPasswordIsValidated(false);
}
};
const onFormSubmit = (e) => {
e.preventDefault();
if (isEmailValid === false) setIsEmailValidated(false);
else if (isPasswordIsValid === false) setIsPasswordIsValidated(false);
else if (isEmailValid && isPasswordIsValid) authCtx.onLogin(emailState, passwordState);
};
return (
<Card>
<form>
<Input
id="email"
label="E-Mail"
type="email"
onChange={onEmailChangeHandler}
onBlur={onEmailBlurHandler}
value={emailState}
isValidated={isEmailValidated}
warningText="Please enter a valid email; must contains '@'"
/>
<Input
id="password"
label="Password"
type="password"
onChange={onPasswordChangeHandler}
onBlur={onPasswordBlurHandler}
value={passwordState}
isValidated={isPasswordIsValidated}
warningText="Password must have 8 characters long"
/>
<Button label="Login" onClick={onFormSubmit} classes={`bgRed bgWider`}></Button>
</form>
</Card>
);
};
export default Login;
1条答案
按热度按时间rslzwgfq1#
在这里,如果不使用归约器,你会有一个简单得多的时间,就像这样:
但是,如果您确实想使用reducer,只需将验证状态与状态更改时的状态相耦合即可: