html - React useState() doesn't update value synchronously
问题描述
React useState() doesn't update value of the variable if called just after setting value.
I read about useEffect(), but don't really know how this will be useful for this particular scenario.
Full code (please open the console tab to see the variable status)
UPDATE
// hook
const [ error, setError ] = useState<boolean>();
const handleSubmit = (e: any): void => {
e.preventDefault();
if (email.length < 4) {
setError(true);
}
if (password.length < 5) {
setError(true);
}
console.log(error); // <== still false even after setting it to true
if (!error) {
console.log("validation passed, creating token");
setToken();
} else {
console.log("errors");
}
};
解决方案
假设用户没有有效的凭据。问题在这里:
if (email.length < 4) { // <== this gets executed
setError(true);
}
if (password.length < 5) { // <== this gets executed
setError(true);
}
console.log(error); // <== still false even after setting it to true
if (!error) { // <== this check runs before setError(true) is complete. error is still false.
console.log("validation passed, creating token");
setToken();
} else {
console.log("errors");
}
您正在使用多个独立运行的 if 检查,而不是使用单个检查。您的代码执行所有 if 检查。在一项检查中,您setError(true)
在满足其中一个条件时调用,但setError()
它是异步的。在调用下一个 if-check 之前,该操作不会完成,这就是为什么它看起来您的值从未保存过。
您可以使用 if-else 和 useEffect 的组合来更干净地做到这一点:https ://codesandbox.io/s/dazzling-pascal-78gqp
import * as React from "react";
const Login: React.FC = (props: any) => {
const [email, setEmail] = React.useState("");
const [password, setPassword] = React.useState("");
const [error, setError] = React.useState(null);
const handleEmailChange = (e: any): void => {
const { value } = e.target;
setEmail(value);
};
const handlePasswordChange = (e: any): void => {
const { value } = e.target;
setPassword(value);
};
const handleSubmit = (e: any): void => {
e.preventDefault();
if (email.length < 4 || password.length < 5) {
setError(true);
} else {
setError(false);
}
};
const setToken = () => {
//token logic goes here
console.log("setting token");
};
React.useEffect(() => {
if (error === false) {
setToken();
}
}, [error]); // <== will run when error value is changed.
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="email@address.com"
onChange={handleEmailChange}
/>
<br />
<input
type="password"
placeholder="password"
onChange={handlePasswordChange}
/>
<br />
<input type="submit" value="submit" />
</form>
{error ? <h1>error true</h1> : <h1>error false</h1>}
</div>
);
};
export default Login;
推荐阅读
- javascript - 从android中的另一个类调用MainActivity方法
- java - Talend Job 在 Windows 服务中不工作
- java - 来自网络的 HTML 内容仅被部分获取/显示
- java - 从文件中读取 N 行并将其保存到新文件中
- java - 将单词标记为古吉拉特语的音节(古吉拉特语字符)
- php - Woocommerce order->get_data() 抛出 PHP 致命错误:未捕获错误
- javascript - javascript中可迭代的格式是什么
- git - Azure Devops中,从Bitbucket拉取时如何选择yaml管道
- javascript - 如何计算包含可能在任何点终止的内部循环的片段的时间复杂度
- css - FontAwesome 图标在相同窗口中的显示方式不同