为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

陪伴而非守候 2022-10-08 17:20:44
如何使用 React 功能挂钩在异步操作后获取更改的状态?我找到了针对这个问题的 redux 解决方案,或者 react 类组件解决方案,但我想知道是否有一个简单的 react 功能解决方案。这是场景:创建一个功能性的反应组件。几个州创建几个按钮元素,每个元素都会改变不同的状态。使用其中一个按钮元素,触发异步操作。如果状态有任何其他变化,在从异步函数接收结果之前,中止所有其他继续操作。附上代码沙箱示例 https://codesandbox.io/s/magical-bird-41ty7?file=/src/App.js
查看完整描述

4 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

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>


查看完整回答
反对 回复 2022-10-08
?
FFIVE

TA贡献1797条经验 获得超6个赞

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


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

 const counterRef = useRef(counter)

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


const newCounter = counter + 1

setCounter(newCounter);

counterRef.current = newCounter

然后检查它:


if (counterRef.current !== counter) {

   alert("counter was changed");

} else {

   setAsyncCounter(counter);

}

Codesandox


查看完整回答
反对 回复 2022-10-08
?
倚天杖

TA贡献1828条经验 获得超3个赞

正如@thedude 所提到的,您将需要使用useRef钩子——它是为您的用例而制作的,正如文档所说:“它可以方便地保留任何可变值,类似于您在类中使用实例字段的方式。”


我想你可能只想添加一个简单的 boolean:


  const counterChanged = useRef(false);

然后当你更新计数器时,你也会更新它。


            counterChanged.current = true;

            setCounter(counter + 1);

在您的 async 函数中,将其设置为 false ,然后检查它是否已更改。


counterChanged.current = false;

            await new Promise(resolve => {

              setTimeout(() => {

                resolve();

              }, 4000);

            });

            if (counterChanged.current) {

            // alert


查看完整回答
反对 回复 2022-10-08
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

通过在 facebook-rect github 上提问,我找到了另一个答案。显然,由于设置状态是一个函数,它的第一个参数是当前状态。


因此可以在设置计数器值时使用此代码段访问先前的值:


 setCounter(prevValue => {

          alert(prevValue + " " + counter);

          return counter + 1;

        });

https://github.com/facebook/react/issues/19270 https://reactjs.org/docs/hooks-reference.html#functional-updates


查看完整回答
反对 回复 2022-10-08
  • 4 回答
  • 0 关注
  • 231 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号