React.js环境下setInterval()单间隔内被调用两次问题求助
问题原因
- 定时器直接写在函数组件顶层,每次组件重新渲染都会生成新的定时器,未做清理的话定时器会不断累积
- React 18+ 开发环境默认开启严格模式,会执行两次组件挂载逻辑,直接生成两个相同间隔的定时器,所以会出现单个间隔内打印两次的现象
- 额外说明:你原有代码中
Date().toLocaleString()写法错误,直接调用Date()返回的是字符串类型,不存在toLocaleString方法,需要改为new Date().toLocaleString()
修复方案
将定时器逻辑放入useEffect钩子中,同时返回清理函数清除旧定时器,保证全局仅存在一个运行中的定时器:
import React, {useState, useEffect} from 'react'; import AppRouter from './Router'; import {authService} from '../fbase'; function App() { console.log('App()'); const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser); console.log(authService.currentUser); useEffect(() => { const timer = setInterval(() => { console.log(new Date().toLocaleString()); console.log('In App.js > App()'); console.log(authService.currentUser); }, 5000); // 组件卸载或依赖更新时清除旧定时器 return () => clearInterval(timer); }, []); // 空依赖数组确保仅首次挂载时创建一次定时器 return <AppRouter isLoggedIn={isLoggedIn}></AppRouter>; } export default App;
这个写法在开发环境严格模式下也不会出现重复定时器的问题,生产环境也能避免组件重渲染导致的定时器累积问题。
内容的提问来源于stack exchange,提问作者yoonjae
相关产品推荐
相关产品推荐

