为什么我的计时器组件在将依赖项传递给 useEffect 时表现奇怪?

我使用以下计时器useEffect并向其传递函数依赖项:


const Timer = () => {

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

  const setId = () => {

    const id = setInterval(() => {

      setCount(count + 1);

    }, 1000);

    return () => clearInterval(id);

  }

  useEffect(() => {

    setId();

  }, [setId])

}

然而计时器的行为很奇怪:前几秒是正常的,然后它开始随机显示计数。是什么导致了这个问题?正确的做法是什么?


回首忆惘然
浏览 77回答 3
3回答

FFIVE

afimport React, { useCallback, useState, useEffect, useRef } from "react";import "./styles.css";export default function App() {  let [count, setCount] = useState(0);  useInterval(() => {    setCount(count + 1);  }, 1000);  return <div className="App">{count}</div>;}function useInterval(callback, delay) {  const savedCallback = useRef();  // Remember the latest callback.  useEffect(() => {    savedCallback.current = callback;  }, [callback]);  // Set up the interval.  useEffect(() => {    function tick() {      savedCallback.current();    }    if (delay !== null) {      let id = setInterval(tick, delay);      return () => clearInterval(id);    }  }, [delay]);}工作代码沙箱更新正如 keith 建议的那样,不要将函数传递给数组 deps,如下所示。import React, { useState, useEffect } from "react";import "./styles.css";export default function App() {  const [count, setCount] = useState(0);  useEffect(() => {    const interval = setInterval(() => {      setCount((count) => count + 1);    }, 1000);    return () => {      clearInterval(interval);    };  }, []);  return <div>{count}</div>;}

守候你守候我

还是不太清楚为什么可以通过[]也许需要更多解释,不幸的是评论太多,所以我发布了这个。要回答这个问题,我们需要退一步,首先问,依赖数组的意义是什么?简单的答案是 useEffect 中任何依赖于某些内容的内容,如果从需要不同处理的 useState 或 Props 进行更改,则需要将其放入数组中。例如,如果您有一个仅显示用户配置文件的组件,但获取此信息是异步的,因此需要 useEffect。它可能看起来像这样 -><UserProfile&nbsp;userId={userId}/>现在的问题是,如果我们[]作为依赖项传递,则 useEffect 不会为新的 userId 重新触发,因此 props 可能会说userId = 2,但我们当前存储在状态中的数据是 for&nbsp;userId = 1,.. 所以对于这样的东西[props.userId]完全有道理。那么回到 OP 的组件,<App/>这里有什么会改变的?好吧,这不是道具,因为没有被传递。那么count您可能会问,我们再次问自己这个问题,计数状态是否保证 setInterval 的新实例被销毁/创建?当然,这里的答案是否定的,因此[]在这里传递是完全有意义的。希望这是有道理的。

ABOUTYOU

清除卸载时的间隔useEffect(() => {&nbsp; &nbsp; let id;&nbsp; &nbsp; const setId = () => {&nbsp; &nbsp; &nbsp; id = setInterval(() => {&nbsp; &nbsp; &nbsp; &nbsp; setCount((count) => count + 1);&nbsp; &nbsp; &nbsp; }, 1000);&nbsp; &nbsp; };&nbsp; &nbsp; setId();&nbsp; &nbsp; return () => clearInterval(id);&nbsp; }, []);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript