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

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

这是场景:

  • 创建一个功能性的反应组件。几个州

  • 创建几个按钮元素,每个元素都会改变不同的状态。

  • 使用其中一个按钮元素,触发异步操作。

  • 如果状态有任何其他变化,在从异步函数接收结果之前,中止所有其他继续操作。

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


陪伴而非守候
浏览 232回答 4
4回答

子衿沉夜

import React, { useState } from "react";import "./styles.css";export default function App() {&nbsp; const [counter, setCounter] = useState(0);&nbsp; const [asyncCounter, setAsyncCounter] = useState(0);&nbsp; return (&nbsp; &nbsp; <div className="App">&nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={async () => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //sets the asyncCounter state to the counter states after a 4 seconds timeout&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let tempCounter = counter;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await new Promise(resolve => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resolve();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 4000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (tempCounter !== counter) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; alert("counter was changed");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAsyncCounter(counter);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }}&nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Async&nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; &nbsp; <label>{asyncCounter}</label>&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //increases the counter state&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setCounter(counter + 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }}&nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Add 1&nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; &nbsp; <label>{counter}</label>&nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; </div>&nbsp; );}<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>

FFIVE

您可以使用 ref 独立跟踪计数器值&nbsp;const [counter, setCounter] = useState(0);&nbsp;const counterRef = useRef(counter)每当您更新 counter 时,您也会更新 counterRef:const newCounter = counter + 1setCounter(newCounter);counterRef.current = newCounter然后检查它:if (counterRef.current !== counter) {&nbsp; &nbsp;alert("counter was changed");} else {&nbsp; &nbsp;setAsyncCounter(counter);}Codesandox

倚天杖

正如@thedude 所提到的,您将需要使用useRef钩子——它是为您的用例而制作的,正如文档所说:“它可以方便地保留任何可变值,类似于您在类中使用实例字段的方式。”我想你可能只想添加一个简单的 boolean:&nbsp; const counterChanged = useRef(false);然后当你更新计数器时,你也会更新它。&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; counterChanged.current = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setCounter(counter + 1);在您的 async 函数中,将其设置为 false ,然后检查它是否已更改。counterChanged.current = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await new Promise(resolve => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resolve();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 4000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (counterChanged.current) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // alert

蝴蝶刀刀

通过在 facebook-rect github 上提问,我找到了另一个答案。显然,由于设置状态是一个函数,它的第一个参数是当前状态。因此可以在设置计数器值时使用此代码段访问先前的值:&nbsp;setCounter(prevValue => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; alert(prevValue + " " + counter);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return counter + 1;&nbsp; &nbsp; &nbsp; &nbsp; });https://github.com/facebook/react/issues/19270 https://reactjs.org/docs/hooks-reference.html#functional-updates
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript