我正在与React Hooks合作,我正在尝试更新状态,然后进行异步操作,然后根据状态进行操作。这不起作用,因为更新功能在异步功能内不可用。您如何使用react hooks解决此类任务?
我基本上试图更改函数的范围,但显然它是不可改变的,这意味着异步函数内部的引用指向旧状态。
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,这应该基于在执行异步功能时已更新的状态来完成。现在,由于异步作用域中的旧引用,它只能每秒钟运行一次。
答案 0 :(得分:3)
只需删除setLoading(false)
通话中的if。
如果不这样做,该功能将访问陈旧的loading
状态。因为创建该函数时,loading
为假。因此,在运行异步功能之后,在等待之后,您的功能将恢复,即使loading
为true
,它也将其视为false。但是您会知道它将是true
,因为只需设置它,并且App
就会在await
语句中重新渲染。请参见以下行为:
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);
答案 1 :(得分:1)
您只需要在异步函数中删除if
条件:
const doSomethingAsync = async () => {
setLoading(true);
await somethingAsync(2000);
setLoading(false);
};