Javascript 在useEffect中使用setInterval时,计时器会发疯

Javascript 在useEffect中使用setInterval时,计时器会发疯,javascript,reactjs,Javascript,Reactjs,所以我一直在努力学习React的基本原理,并尝试了类似的东西,这让代码变得疯狂。从最初的数字开始,看起来所有的数字变化都非常快,过了一段时间,浏览器会发出如下警告 “设置间隔”需要205ms 尝试将计时器添加为依赖项,甚至返回它。这让我有点困惑。有人能给我详细解释一下这里发生了什么吗 import {useState, useEffect} from 'react' function App() { const [timer, setTimer] = useState(0) use

所以我一直在努力学习React的基本原理,并尝试了类似的东西,这让代码变得疯狂。从最初的数字开始,看起来所有的数字变化都非常快,过了一段时间,浏览器会发出如下警告

“设置间隔”需要205ms

尝试将计时器添加为依赖项,甚至返回它。这让我有点困惑。有人能给我详细解释一下这里发生了什么吗

import {useState, useEffect} from 'react'

function App() {

  const [timer, setTimer] = useState(0)

  useEffect(()=>{

    setInterval(()=>{
      setTimer(timer + 1)
    }, 1000)
  },[timer])

  return (
    <>
      <h1>Timer : {timer}</h1>
    </>
  );
}

export default App;
从'react'导入{useState,useffect}
函数App(){
常量[timer,setTimer]=useState(0)
useffect(()=>{
设置间隔(()=>{
设置计时器(计时器+1)
}, 1000)
},[计时器])
返回(
计时器:{Timer}
);
}
导出默认应用程序;

请解释

您需要从
useffect
中删除
计时器
作为依赖项,否则每次更新
计时器
时,它将重新创建另一个间隔

您可能还希望在钩子清理过程中使用
clearInterval
清除间隔,即组件卸载时(在本例中)

同样,您需要执行
setTimer(prev=>prev+1)
读取上一个(最新状态)并递增到它

函数应用程序(){
const[timer,setTimer]=React.useState(0)
React.useffect(()=>{
常量id=setInterval(()=>{
设置计时器((上一个)=>上一个+1)
}, 1000)
return()=>{
清除间隔(id)
}
}, [])
返回计时器:{Timer}
}
ReactDOM.render(,document.getElementById('mydiv'))


如果您的
useffect
依赖项数组包含您在其中设置的状态,它将形成一个无限循环,因为每次设置状态时,
useffect
都将再次调用。在那里不需要添加它,只要改变<代码> [定时器] <代码> > <代码> [COD] >使其空置依赖关系。也考虑访问您的代码> PREV状态,以设置新的<代码>定时器< /代码>:<代码> SETIMER(PREV= > PREV + 1)为什么不直接使用
setTimeout
而不是
setInterval
?您不需要对setInterval id使用ref。它可能只是useffect函数闭包中的局部变量。我知道它们是如何工作的,谢谢。我只是觉得在这种情况下使用
setTimeout
要容易得多,不需要清理任何东西-