【问题标题】:Handling out of date state in functional components处理功能组件中的过期状态
【发布时间】:2019-07-15 02:59:47
【问题描述】:

我在从异步函数中设置使用“useState”挂钩创建的状态时遇到问题。

我创建了一个代码笔来演示:https://codepen.io/james-ohalloran/pen/ZdNwWQ

const Counter = () => {
  const [count, setCount] = useState(0);

  const increase = () => {
    setTimeout(() => {
      setCount(count + 1);
    },1000);
  }

  const decrease = () => {
    setTimeout(() => {
    setCount(count - 1);
    },1000)
  };
  return (
    <div className="wrapper">
      <button onClick={decrease}>-</button>
      <span className="count">{count}</span>
      <button onClick={increase}>+</button>
    </div>
  );
};

在上面的例子中,如果你点击“增加”,然后点击“减少”..你最终会得到 -1(我希望它是 0)。 如果这是一个 React 类而不是函数组件,我会假设解决方案是在函数上使用 bind(this),但我没想到这是箭头函数的问题。

【问题讨论】:

  • console.log(count) 高于return 语句会得到什么?
  • 为什么要使用 setTimeout?
  • 我实际上并没有在我的应用程序中使用 setTimout。我正在等待网络请求完成,然后更改错误列表。这只是同一问题的一个更简单的示例

标签: reactjs react-16


【解决方案1】:

因为使用setTimeout

假设您在一秒钟内调用了 increase() 10 次。

count 将始终为0。因为状态在一秒钟后更新,所以在一秒钟内调用的每个increment() 都会有一个未更新的count

所以每个increment() 都会调用setCount(0 + 1);

所以无论你在一秒钟内调用多少次,count 始终是1

【讨论】:

  • 是的,我可以确认这是我在注销计数时看到的行为。您如何建议对其进行重组,以便 setTimeout 回调中的代码可以访问新状态?
【解决方案2】:

啊,我找到了解决办法。我没有意识到我能够从 useState setter 函数中引用 previousState:https://reactjs.org/docs/hooks-reference.html#functional-updates

【讨论】:

    猜你喜欢
    • 2021-05-09
    • 1970-01-01
    • 2017-11-29
    • 2018-09-29
    • 2022-01-20
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多