【问题标题】:setState inside setInterval not working as expected. Any Idea why?setInterval 中的 setState 未按预期工作。任何想法为什么?
【发布时间】:2021-01-13 21:14:00
【问题描述】:

我想每 2 秒更新一次状态并渲染一些图像 这绝对没问题

useEffect(() => {
    setTimeout(() => {
      if (workImages.currentIndex > workImages.items.length - 2) {
        setWorkImages({ ...workImages, currentIndex: 0 });
      } else {
        setWorkImages({
          ...workImages,
          currentIndex: ++workImages.currentIndex,
        });
      }
    }, 2000);
  }, [workImages]);

这仅适用于其他情况

useEffect(() => {
    setInterval(() => {
      if (workImages.currentIndex > workImages.items.length - 2) {
        setWorkImages({ ...workImages, currentIndex: 0 });
      } else {
        setWorkImages({
          ...workImages,
          currentIndex: ++workImages.currentIndex,
        });
      }
    }, 2000);
  }, []);

谁能解释一下原因?

【问题讨论】:

  • 是的,因为 setInterval 在每个给定时间(在本例中为 2 秒或 2000 密耳)后执行函数。但是 setTimeout 会在给定时间后执行一次函数。

标签: reactjs react-hooks settimeout setinterval setstate


【解决方案1】:

假设workImages.currentIndex 从 1 开始。

在第一个示例中,第一次调用函数时,useEffect 被设置,2 秒后setTimeout 被触发。这会将状态更新为 workImages.currentIndex 现在是 2,这会触发重新渲染。现在workImages 已更改,由于它是useEffect 的依赖项,因此再次调用该函数,两秒后又运行一次超时。

现在在第二个示例中,第一次调用函数时会发生非常相似的情况,但第二次调用useEffect 时不会再次运行。不依赖于workImages

现在,您可能这无关紧要,因为您使用的是 setInterval 而不是 setTimeout,而且您几乎是对的。

2 秒后,间隔触发,您传递给它的函数再次运行。

然而它已经关闭 workImages 变量从第一次函数运行时开始,而不是第二次。 workImages.currentIndex 的值(就该函数而言)仍然是 1,因为它没有从状态中获得更新的值。所以它再次将其设置为 2。这不是更改(它已经是 2,因此您不会重新渲染。2 秒后,它再次将其设置为 2,并且一直如此。

【讨论】:

    【解决方案2】:

    第一个示例之所以有效,是因为它侦听 workImages。因此,每次 workImages 发生变化时,您都会使用 setWorkImages 设置一个新图像。

    第二个示例仅在页面加载时触发 ONCE

    有关 useEffect 的更多信息,请看这里:https://reactjs.org/docs/hooks-effect.html

    【讨论】:

      【解决方案3】:

      第一个有效,因为您已将workImages 数组包含在您的依赖数组中:只要workImages 更改,挂钩就会触发。

      您的第二个示例有一个空依赖数组,这意味着它会在组件挂载时触发一次,但不会在 workImages.currentIndex 更改时重新触发。

      【讨论】:

        猜你喜欢
        • 2019-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-05
        • 2022-01-24
        • 2021-07-10
        • 1970-01-01
        相关资源
        最近更新 更多