【问题标题】:Different behaviour of setInterval in react vs vanilla javascriptreact vs vanilla javascript中setInterval的不同行为
【发布时间】:2021-10-24 17:48:49
【问题描述】:

我一直在尝试setInterval。这两个代码都是在 Chrome 中执行的。下面是我的反应组件

function App() {
  let [value, setValue] = useState(0);

  useEffect(() => {
    const id = setInterval(() => console.log(value), 1000);

    return () => clearInterval(id);
  }, []);

  return (
    <div className="App">
      <p>{value}</p>

      <button onClick={() => setValue(value + 1)}>+</button>
      <button onClick={() => setValue(value - 1)}>-</button>
    </div>
  );
}

setTimeout 内的useEffect 中的console.log 会不断打印0,无论您通过按钮单击增加减少 值的次数。

以下代码正在浏览器 (Chrome) 控制台中执行

let value = 0;

setInterval(() => console.log(value), 1000);

value = 3; // can be considered as setValue (sort of)

现在浏览器控制台打印3,这是预期的。

我想知道为什么行为会有所不同,如果有人能指出原因,我将不胜感激。任何其他可以更好地证明这一点的代码 sn-p 或链接都会很棒。

【问题讨论】:

标签: javascript reactjs setinterval setstate


【解决方案1】:

您需要将 value 作为依赖项传递给您的 useEffect。除非你在依赖数组中给出你的效果依赖的项目列表,否则它将继续使用初始的value

  useEffect(() => {
    const id = setInterval(() => console.log(value), 1000);

    return () => clearInterval(id);
  }, [value]);

【讨论】:

  • 这将导致console.log 在每次点击后和每次点击后发生一秒钟,我认为这不是问题所要求的。
  • @Houssam 你为什么会这样想?据我所知,这正是 OP 想要的。
  • 这是我对这个问题的理解,是什么让我对解释是什么感到好奇。我的理解是useEffect 触发setInterval,然后 OP 在 1 秒内单击“+”按钮并期望在控制台中看到“1”,但看到“0”。
  • @Houssam 是对的。代码的目的不是在每次点击后触发console.log。它只是每 1 秒打印一次值,而不考虑任何点击。此外,如果 value 在依赖项数组中传递,那么每次 value 更改时,它都会简单地重新创建具有最新值的间隔,这将正常工作。
  • @RishabhSingh 是的,再次,就像它在这个(正确)答案中所说的那样,您必须将 value 添加到依赖项数组. 沙箱中的那个数组下面甚至还有黄色的波浪线,因为 linter 已经在抱怨它了
【解决方案2】:

在您的示例中,useEffect 仅在页面加载时工作一次。这就是为什么你只会得到 console.log(0)。如果要在值更改时进行,则需要在 useEffect 中指定

例如

UseEffect(() =>{ console.log(value) }, [value])

在您的示例中,当您单击按钮时,第一个值会在 useEffect 起作用并且 setInternals 函数在 1 秒后触发。

【讨论】:

  • useEffect 在您点击之前就可以工作。
猜你喜欢
  • 2016-08-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多