何时调用 clearInterval - 当计时器更改时或当卸载与 setInterval 关联的渲染时

When clearInterval will be called - When the timer changes or When the render is unmounted with which the setInterval is associated

我是 React 的初学者,遇到了一些问题。 何时清除与特定渲染关联的 setInterval?



import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";

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

  useEffect(() => {
    let id = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(id);
  },[]);

  return <h1>{count}</h1>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Counter />, rootElement);

它将在组件卸载事件中被清除:

useEffect(() => {
    let id = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(id); // <-- get called on component unmount
  },[]); // <--- get called once component mounted/rendered first time

更多详情:DO READ

When exactly does React clean up an effect?

React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React also cleans up effects from the previous render before running the effects next time.

我认为你的实际问题是定时器只更新一次,对吧?那是因为你 lied to React about your dependencies,你的效​​果使用 count,将其添加为依赖项:

 useEffect(() => {
   let id = setInterval(() => {
     setCount(count + 1); // here you use count
   }, 1000);
   return () => clearInterval(id);
 }, [count]); // here you have to tell react about your dependencies

现在,每当 count 更改或组件卸载时,都会调用效果返回的函数。所以你实际上可以把你的代码写成:

 useEffect(() => {
   let id = setTimeout(() => {
     setCount(count + 1);
   }, 1000);
   return () => clearTimeout(id);
 }, [count]);

这基本上是这样做的:每当 'count' 改变时,安排一个计时器在 1 秒内再次改变 'count'

然而,使用只要组件被挂载就运行的时间间隔也可以,但要让它起作用,我们需要 (1) 删除所有依赖项 (count) 和 (2) 获取最新 count 以某种方式。幸运的是状态 setter 也接受回调:

 useEffect(() => {
   let id = setInterval(() => setCount(count => count + 1), 1000);
   return () => clearInterval(id);
 }, []); // we don't lie anymore