我正在使用 React Hooks,我正在尝试更新状态,然后执行一些异步操作,然后根据状态执行一些操作。这不起作用,因为更新状态在异步函数中不可用。你怎么能用 react 钩子(Hook)解决这样的任务?
Demo
我基本上试图改变函数的范围,但显然它都是不可变的,这意味着异步函数内部的引用指向旧状态。
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
// Constants
function somethingAsync(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function App() {
const [loading, setLoading] = React.useState(false);
const doSomethingAsync = async () => {
setLoading(true);
await somethingAsync(2000);
if (loading) {
setLoading(false);
}
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<p>Current Status: {loading ? "Loading" : "Not Loading"}</p>
<button onClick={doSomethingAsync}>Do Something Async</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
我希望每次完成异步功能时将加载标志重置回 false,这应该基于在执行异步功能时已更新的状态来完成。现在,由于异步范围内的旧引用,它只能每隔一次工作一次。
最佳答案
只需删除 setLoading(false)
调用周围的 if 即可。
如果不这样做,该函数将访问陈旧的 loading
状态。因为在创建该函数时,loading
为 false。因此,在运行 async 函数之后,在 await 之后,您的函数将恢复,即使 loading
是 true
它也会将其视为 false。但是您会知道它将是 true
,因为您刚刚设置了它并且您的 App
已在 await
语句中重新呈现。请参阅以下行为:
CodeSandbox
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
// Constants
function somethingAsync(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function App() {
const [loading, setLoading] = React.useState(false);
console.log("App rendering...");
const doSomethingAsync = async () => {
setLoading(true);
console.log("Before await...");
await somethingAsync(2000);
console.log("After await...");
setLoading(false);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<p>Current Status: {loading ? "Loading" : "Not Loading"}</p>
<button onClick={doSomethingAsync}>Do Something Async</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
关于javascript - 如何使用 React Hooks API 管理异步函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57320769/