React useState() 不会同步更新值



React useState() 如果在设置值后调用,则不会更新变量的值。

我读过关于useEffect()的信息,但真的不知道这对这个特定场景有什么用处。

完整代码(请打开控制台选项卡以查看变量状态)

更新

// 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;

就像setState一样,useState是异步的,并且倾向于将更新批量更新在一起,以提高性能。 您在使用useEffect的正确轨道上,这将允许您在状态更新后有效地执行回调。

文档中的示例:

import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

尽管还建议,如果在请求更新状态后立即需要更新的值,但最好只在组件中使用一个变量。

详细了解如何同步使用状态

如果你熟悉Redux的reducer,你可以使用useReducer作为另一种选择。 从文档中:

useReducer 通常比 useState 更可取,当你有复杂的 涉及多个子值或下一个状态时的状态逻辑 取决于前一个。useReducer 还允许您优化 触发深度更新的组件的性能,因为您可以 传递调度而不是回调。

相关内容

  • 没有找到相关文章

最新更新