如何使用 React 功能挂钩在异步操作后获取更改的状态

Sha*_*chi 8 javascript state functional-programming async-await reactjs

如何使用 React 功能挂钩在异步操作后获取更改的状态?我已经为这个问题找到了一个 redux 解决方案,或者一个 react 类组件解决方案,但我想知道是否有一个简单的 react 功能解决方案。

这是场景:

  • 创建一个功能性的反应组件。几个州
  • 创建多个按钮元素,每个元素都会改变不同的状态。
  • 使用按钮元素之一,触发异步操作。
  • 如果状态有任何其他变化,在从异步函数接收结果之前,中止所有其他持续操作。

附上代码沙箱示例 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>
  );
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

the*_*ude 8

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

 const [counter, setCounter] = useState(0);
 const counterRef = useRef(counter)
Run Code Online (Sandbox Code Playgroud)

每当您更新 counter 时,您也会更新 counterRef:

const newCounter = counter + 1
setCounter(newCounter);
counterRef.current = newCounter
Run Code Online (Sandbox Code Playgroud)

然后检查它:

if (counterRef.current !== counter) {
   alert("counter was changed");
} else {
   setAsyncCounter(counter);
}
Run Code Online (Sandbox Code Playgroud)

Codesandox