reactjs 如何使用React函数钩子在异步操作后获取更改后的状态

omhiaaxx  于 2023-03-12  发布在  React
关注(0)|答案(3)|浏览(131)

如何使用React函数钩子在异步操作后获得改变的状态?我已经找到了这个问题的redux解决方案,或者react类组件解决方案,但我想知道是否有简单的react函数解决方案。
以下是场景:

  • 创建具有很少状态的功能性React组件
  • 创建几个按钮元素,每个按钮元素改变不同的状态。
  • 使用按钮元素之一触发异步动作。
  • 如果状态中有任何其他更改,则在从async函数接收结果之前,中止所有其他继续的操作。

附件是代码沙箱示例https://codesandbox.io/s/magical-bird-41ty7?file=/src/App.js

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [counter, setCounter] = useState(0);
  const [asyncCounter, setAsyncCounter] = useState(0);
  return (
    <div className="App">
      <div>
        <button
          onClick={async () => {
            //sets the asyncCounter state to the counter states after a 4 seconds timeout
            let tempCounter = counter;
            await new Promise(resolve => {
              setTimeout(() => {
                resolve();
              }, 4000);
            });
            if (tempCounter !== counter) {
              alert("counter was changed");
            } else {
              setAsyncCounter(counter);
            }
          }}
        >
          Async
        </button>
        <label>{asyncCounter}</label>
      </div>
      <div>
        <button
          onClick={() => {
            //increases the counter state
            setCounter(counter + 1);
          }}
        >
          Add 1
        </button>
        <label>{counter}</label>
      </div>
    </div>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
6jjcrrmo

6jjcrrmo1#

您可以使用ref独立跟踪计数器值

const [counter, setCounter] = useState(0);
 const counterRef = useRef(counter)

每当更新计数器时,也会更新counterRef:

const newCounter = counter + 1
setCounter(newCounter);
counterRef.current = newCounter

然后检查:

if (counterRef.current !== counter) {
   alert("counter was changed");
} else {
   setAsyncCounter(counter);
}

Codesandox

2q5ifsrm

2q5ifsrm2#

我在facebook上找到了另一个答案-rect github.显然,由于设置状态是一个函数,它的第一个参数就是当前状态。
因此,在设置计数器值时,可以通过使用以下代码段访问以前的值:

setCounter(prevValue => {
          alert(prevValue + " " + counter);
          return counter + 1;
        });

https://reactjs.org/docs/hooks-reference.html#functional-updates

elcex8rz

elcex8rz3#

正如@thedude提到的,您将需要使用useRef钩子-它完全是为您的用例而设计的,正如文档所述:“这对于保持任何可变值都很方便,就像在类中使用示例字段一样。”
我认为您可能只需要添加一个simple boolean

const counterChanged = useRef(false);

当你更新计数器的时候,这个也要更新。

counterChanged.current = true;
            setCounter(counter + 1);

在异步函数中,你把它设为false然后检查它是否被修改过。

counterChanged.current = false;
            await new Promise(resolve => {
              setTimeout(() => {
                resolve();
              }, 4000);
            });
            if (counterChanged.current) {
            // alert

相关问题