我想在页面加载时启动一个计时器,我的代码如下:
function App() {
const [sec, setSec] = useState(0);
useEffect(()=>{
setInterval(()=>{setSec(prev=>prev+1)
}, 1000)}, [sec])
return (
<span>{sec}</span>
)}
字符串
但是计数器的增量不是每秒钟,而是非常快。我不知道问题是什么。
我认为setInterval()
将每秒运行一次,这会更新sec
变量,而sec
变量又会调用useEffect()
中的回调函数,以便它可以再次运行。
我确实在网上找到了一些设置react计时器的示例代码,但是他们使用useRef()
来保存setInterval()
回调函数,然后更新sec
变量,比如setSec(sec+1)
。我粗略地理解了其中的逻辑,但并不完全理解,我不明白为什么我的代码不起作用。
如果有人能帮助我,非常感谢。如果我错过了一些简单的事情,我很抱歉。
1条答案
按热度按时间8e2ybdfx1#
我看到两个问题。
首先,从
useEffect
的依赖数组中删除sec
。你应该使用一个间隔 * 或 * 作为效果依赖,但不能同时使用。当你同时使用这两种方法时,你实际上是在每次重新渲染时创建一个新的间隔,所以每次重新渲染都会增加增量的数量,并且速率将无限地复合。如果你想依赖数组和在每个渲染上重新运行的效果,你只需要使用
setTimeout
而不是setInterval
。例如:字符串
这样,组件的每次重新渲染(以及效果的每次重新调用)只执行一个增量,而不是增量集的新的持续间隔。
第二,也是更微妙的一点,这种影响会留下一个没有被清除的副作用。如果组件在技术上渲染两次,这在开发环境中会很明显,并且你会看到你的计数器每秒增加2而不是1。
你可以通过从
useEffect
回调中返回一个cleanup函数来“清理”一个效果。当组件卸载时,React会使用这个函数。例如:型