【问题标题】:setInterval behaving sporadically in React appsetInterval 在 React 应用程序中偶尔出现
【发布时间】:2021-09-08 22:52:20
【问题描述】:

我正在尝试将一些数据转换为间隔状态,我正在尝试制作每 x 秒更新一次的图表。

fuction func() {
    console.log('Hello, world!')
}

setInterval(func, 5000)

我不是像预期的那样每 5 秒响应一次,而是每 10 秒得到两个响应,当我尝试按照我真正想要的状态进行转换时,这个问题会变得更糟。

这是我的 API 调用的响应,我要做的就是将其转换为 state 并记录结果。


{
  "_id": "60d5e8a81a68bb7b14d9f3b0",
  "symbol": "LTC",
  "perc": "3.55",
  "createdAt": "2021-06-25T14:31:04.677Z",
  "updatedAt": "2021-06-25T14:31:04.677Z",
  "__v": 0
}

当我使用下面的代码时,而不是双倍的结果,它绝对是一团糟。


let [ltcArb, setLtcArb] = useState([]);

    const fetchLtcArbHandler = () => {
        fetch("/arb/ltc")
            .then((res) => res.json())
            .then((json) => setLtcArb((prev) => [{ perc: json.perc, time: json.createdAt },...prev,]))
            .then(console.log(ltcArb));
    };

    function poes() {
        console.log("poes");
    }

    setInterval(fetchLtcArbHandler, 5000);

我已经为此苦苦思索了好几个小时,老实说昨晚失眠了。任何和所有的帮助都将不胜感激,请放轻松我在这里还是很新的。谢谢

【问题讨论】:

  • 您可以使用浏览器“网络”开发者工具来检查 HTTP 请求何时发生。从您发布的代码中,几乎不可能知道发生了什么。 setInterval() 方法不能保证绝对准确,但在您的情况下应该非常接近 5 秒。
  • setInterval 是否在函数组件的主体中?如果是这样,它将在每次渲染时创建一个新的间隔,这将导致函数调用的数量无限增加。

标签: javascript reactjs asynchronous fetch


【解决方案1】:

那是因为您使用的功能组件实际上是组件的渲染功能

每次重新渲染组件时都会执行它,因此每次更改状态时都会执行。

您需要将它封装在一个 useEffect 中,并带有一个像这样的空依赖数组:

useEffect(() => setInterval(fetchLtcArbHandler, 5000), []);

另外,你需要返回一个清理函数,否则即使组件卸载,请求也会无限期运行,同时还会因为潜在的闭包上下文引用而导致内存泄漏:

useEffect(() => {
  const interval = setInterval(fetchLtcArbHandler, 5000);
  return () => clearInterval(interval);
}, []);

【讨论】:

  • 感谢您的评论,奇怪的是,当我不使用清理功能时,它的行为几乎符合预期,但当我使用它时,它又开始以两倍的时间更新。在我运行按钮的 fetchLtcArbHandler onClick 时,它会添加到状态中,但当函数被 useEffect 和 setInterval 调用时,它不会添加到状态中,有什么想法吗?谢谢
  • 没有看到完整代码很难说,我猜你写的是onClick={fetchLtcArbHandler()}而不是onClick={() => fetchLtcArbHandler()}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2011-01-08
相关资源
最近更新 更多