SetInterval 导致 React 重新渲染次数过多

Kay*_*Kay 1 javascript reactjs

你好,我想将 setInterval 放入我的 React 项目中,每秒加 1,但我收到了像本文标题一样的错误。js:

const [activeTab, setActiveTab] = useState(0)
useEffect(() => {
       setInterval(setActiveTab(prevTab => {
           if (prevTab === 3) return 0
           console.log('hi')
           return prevTab += 1
               
       }), 1000)
   
   })
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

有几个问题:

\n
    \n
  1. 您不是将函数传递给setInterval,而是调用 setActiveTab返回值并将其传递给setInterval

    \n
  2. \n
  3. 如果您传入一个函数,则每次组件运行时都会添加一个新的重复计时器。请参阅文档\xc2\xa0\xe2\x80\x94 useEffect

    \n
    \n

    默认情况下,效果在每次完成渲染后运行...

    \n
    \n

    setInterval

    \n
    \n

    setInterval()方法...重复调用函数或执行代码片段,每次调用之间有固定的时间延迟。

    \n
    \n

    (我的重点)

    \n

    每次组件重新渲染时启动一个新的重复计时器会创建大量重复计时器。

    \n
  4. \n
  5. 如果组件被卸载,您的组件将使间隔计时器保持运行。它应该停止间隔计时器。

    \n
  6. \n
\n

要修复它,请传入一个函数,添加一个依赖项数组,并添加一个清理回调来停止间隔:

\n
const [activeTab, setActiveTab] = useState(0);\nuseEffect(() => {\n    const handle = setInterval(() => { // *** A function\n        setActiveTab(prevTab => {\n            if (prevTab === 3) return 0;\n            console.log("?ghi");\n            return prevTab += 1;\n        });\n    }, 1000);\n    return () => {              // *** Clear the interval on unmount\n        clearInterval(handle);  // ***\n    };                          // ***\n}, []); // *** Empty dependency array = only run on mount\n
Run Code Online (Sandbox Code Playgroud)\n
\n

旁注:假设您不需要console.log,则通过使用余数运算符,状态设置器回调函数可以更简单:

\n
setActiveTab(prevTab => (prevTab + 1) % 3);\n
Run Code Online (Sandbox Code Playgroud)\n