【问题标题】:Weird interaction between setTimeout and state set function [closed]setTimeout 和状态集函数之间的奇怪交互
【发布时间】:2020-12-24 06:55:46
【问题描述】:

给定这个代码sn-p:

const [filled, setFilled] = useState(0);
//...
useEffect(() => {
    console.log("start");
    setFilled(() => {
      setTimeout(() => {
        console.log("old1");
        setFilled(() => {
          setTimeout(() => {
            console.log("old2");
          }, 1000);
          return 20;
        });
        console.log("old3");
      }, 1000);
      return 10;
    });
  }, []);

谁能解释为什么 old2 被打印两次? 我知道代码很奇怪,但我仍然没有想法。它必须与功能状态集功能的内部 React 处理有关,但我无法在文档中找到任何解释。

谢谢。

【问题讨论】:

  • “我有奇怪的代码,我不知道它做了什么,但它做了一些奇怪的事情” - 听起来像 X/Y 问题
  • 这只是递归 setTimeout 的简化版本,所以并不奇怪。
  • 你想在这里达到什么目的?
  • @ksav,我正在尝试执行某些操作 - 在这种情况下,console.log 每秒一次。这段代码唯一缺少的是递归 setTimeout,它在每次迭代中将操作加倍 - 这意味着它将打印 old2 4、8、16 次等等。
  • 所以你每秒钟都在尝试设置状态?请参阅meta.stackexchange.com/questions/66377/what-is-the-xy-problem 并考虑编辑您的问题。

标签: javascript reactjs


【解决方案1】:

setTimeout()setFilled() 都在执行 asynchronously。而且我们无法确定何时重新调整结果,这就是您有这种行为的原因。

【讨论】:

    【解决方案2】:

    你违反了 React 提供的接口契约。 setState() updater 函数必须是纯函数,即没有副作用。

    之所以需要这样做,是因为 React 不保证更新函数将被调用的时间或次数。

    即使您认为您已经确定了这种情况下的具体行为,它也可能会在下一个版本中更改,恕不另行通知,所以不要试图依赖从这个“奇怪”代码中可以观察到的内容.

    【讨论】:

      猜你喜欢
      • 2015-12-24
      • 1970-01-01
      • 2015-07-30
      • 2016-12-13
      • 2019-05-25
      • 1970-01-01
      • 2013-12-04
      • 2020-05-20
      • 1970-01-01
      相关资源
      最近更新 更多