简体   繁体   English

即使在使用 clearInterval() 清除 setInterval() 后,它也会继续运行

[英]setInterval() keeps running even after clearing it using clearInterval()

Most of the answers I found here was to use clearInterval() inside a return statement in a useEffect().我在这里找到的大多数答案是在 useEffect() 的 return 语句中使用 clearInterval()。 But, still for some reasons it keeps executing.但是,由于某些原因,它仍然会继续执行。

I'm also getting the following warning in the logs:-我还在日志中收到以下警告:-

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    in StartTest (at SceneView.tsx:126)

attaching the code for Reference.附上参考代码。

const [connectionInterval, setConnectionInterval] = useState(null);
const [batteryInterval, setBatteryInterval] = useState(null);
const [heartRateInterval, setHeartRateInterval] = useState(null);

useEffect(() => {
    startServices();
    return () => {
      clearServices();
    };
}, []);


const startServices= () => {
    let ctnInt = setInterval(() => checkConnection(), 5000);
    setConnectionInterval(ctnInt);
    let btryInt = setInterval(
      () =>
        Battery(value => {
          setBattery(value);
        }),
      900000,
    );
    setBatteryInterval(btryInt);
    let hrRtInt = setInterval(
      () =>
        HeartRate(
          hr => {
            if (finish) {
              clearInterval(heartRateInterval);
            }
            let rate = Math.round(hr);
            setHeartRate(rate);
          },
          onError => {
            console.log('API ERROR');
          },
        ),
      3000,
    );
    setHeartRateInterval(hrRtInt);
  };


  const clearServices = () => {
    clearInterval(connectionInterval);
    clearInterval(batteryInterval);
    clearInterval(heartRateInterval);
  };```

I had this issue a couple of weeks ago and what I did to stop it was to set a new state after clearing the interval .几周前我遇到了这个问题,为了阻止它,我在清除间隔后设置了一个新的 state

For example.例如。 I was trying to build a countdown that ran from 30 to 0 and stop at 0. This is what I did我试图建立一个从 30 到 0 并停在 0 的倒计时。这就是我所做的

const [timeRemaining, setTimeRemaining] = useState(30);

useEffect(() => {
  let timeLeft = timeRemaining;
  let interval = setInterval(() => {
    if (timeLeft === 0) {
      clearInterval(interval);
      setTimeRemaining(0);
    } else {
      setTimeRemaining((timeLeft -= 1));
    }
  }, 1000);
}, [timeRemaining]);

Setting the state to 0 after clearing the interval was the only way to stop the countdown timer at 0清除间隔后将 state 设置为 0 是将倒数计时器停止在 0 的唯一方法

You're not passing any deps to useEffect , so the effect functions never update, and in the version of clearServices that you call, connectionInterval and friends are all still null .您没有将任何 deps 传递给useEffect ,因此效果函数永远不会更新,并且在您调用的clearServices版本中, connectionInterval和朋友仍然是null See the note here .请参阅此处的注释。

In general I would approach setInterval like this:一般来说,我会像这样接近setInterval

useEffect(() => {
    const intervalFn = () => {
        console.log('interval fired')
    }
    const intervalId = setInterval(intervalFn, 1000)
    return () => {
        clearInterval(intervalId)
    }
}, [])

(this version really has no deps, because everything is captured inside useEffect. but in practice you would probably have some.) (这个版本真的没有依赖,因为一切都在 useEffect 中捕获。但实际上你可能会有一些。)

In useEffect, you should declare dependencies in array after callback function.在useEffect中,你应该在回调function之后在数组中声明依赖。 In the code above, startServices is dependency, because it is declared outside the useEffect.在上面的代码中, startServices是依赖项,因为它是在 useEffect 之外声明的。

https://reactjs.org/docs/hooks-reference.html#useeffect https://reactjs.org/docs/hooks-reference.html#useeffect

You can learn about useEffect in link.您可以在链接中了解 useEffect 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM