首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用React Hooks API管理异步函数

如何使用React Hooks API管理异步函数
EN

Stack Overflow用户
提问于 2019-08-02 14:05:56
回答 2查看 83关注 0票数 3

我正在使用React Hooks,我正在尝试更新状态,然后做一些异步的事情,然后根据状态做一些事情。这不起作用,因为更新状态在async函数中不可用。如何使用react钩子解决这样的任务?

Demo

我基本上试图改变函数的作用域,但显然它都是不可变的,这意味着异步函数内部的引用指向旧状态。

代码语言:javascript
复制
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,这应该根据异步函数的状态进行更新。现在,由于异步作用域中的旧引用,它只能每隔一秒工作一次。

EN

回答 2

Stack Overflow用户

发布于 2019-08-02 15:26:05

只需删除setLoading(false)调用两边的if即可。

如果不这样做,该函数将访问过时的loading状态。因为在创建该函数时,loading是false。因此,在您运行异步函数之后,在等待之后,您的函数将恢复,即使loadingtrue,它也会将其视为false。但是您将知道它将是true,因为您刚刚设置了它,并且您的App已经在await语句中重新呈现。请参见下面的行为:

CodeSandbox

代码语言:javascript
复制
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);
票数 3
EN

Stack Overflow用户

发布于 2019-08-02 14:09:55

您只需要删除异步函数中的if条件:

代码语言:javascript
复制
  const doSomethingAsync = async () => {
      setLoading(true);
      await somethingAsync(2000);
      setLoading(false);      
    };
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57320769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档