ReactJS无活动10分钟自动登出功能异常排查
修复React用户无活动自动登出问题
你的代码存在几个核心问题,导致无论用户是否活跃都会强制登出:
- 定时器变量未持久化:用
var timer声明的变量会在组件重渲染时丢失引用,导致无法正确清除旧定时器。 - 初始未启动定时器:只有用户触发事件后才会启动定时器,页面加载后若用户不操作,定时器永远不会触发。
- 事件监听清理不完整:组件卸载时未清理事件监听器和定时器,会引发内存泄漏。
- 时间参数错误:你写的
1000000是16分钟左右,10分钟对应的毫秒数应为600000(10601000)。
修复后的完整代码
import { useEffect, useRef } from 'react'; import { Row, Col } from 'antd'; import Aside from './Aside'; import Navbar from './Navbar'; import { Outlet, useNavigate } from 'react-router-dom'; const Layout = () => { const timerRef = useRef(null); // 用useRef持久化定时器引用 const navigate = useNavigate(); const events = [ "load", "mousemove", "mousedown", "click", "scroll", "keypress", ]; // 执行登出操作 const logoutAction = () => { localStorage.clear(); console.log("Sign out"); navigate('/signin'); // 跳转到登录页 }; // 重置定时器:清除旧的,启动新的 const resetTimer = () => { if (timerRef.current) { clearTimeout(timerRef.current); } // 设置10分钟后登出的新定时器 timerRef.current = setTimeout(() => { logoutAction(); }, 600000); // 10分钟 = 600000毫秒 }; useEffect(() => { // 页面加载时启动初始定时器 resetTimer(); // 给每个事件添加监听,触发时重置定时器 const handleActivity = () => resetTimer(); events.forEach(event => { window.addEventListener(event, handleActivity); }); // 组件卸载时清理监听器和定时器 return () => { if (timerRef.current) { clearTimeout(timerRef.current); } events.forEach(event => { window.removeEventListener(event, handleActivity); }); }; }, [navigate]); return ( <div> <Row> <Col lg={5} className=''> <Aside /> </Col> <Col xl={19} lg={19} md={19} sm={24} xs={24}> <Row> <Col span={24}> <Navbar /> </Col> <Col span={24}> <div className="outlet"> <Outlet /> </div> </Col> </Row> </Col> </Row> </div> ) } export default Layout
关键修复点说明
- 用
useRef存储定时器:确保组件重渲染时不会丢失定时器引用,能正确清除旧定时器。 - 初始启动定时器:组件挂载时立即调用
resetTimer,保证页面加载后就开始计时。 - 统一事件处理函数:把事件监听的回调抽成单独函数
handleActivity,这样卸载时能正确移除监听(匿名函数无法被移除)。 - 组件卸载清理:在
useEffect的返回函数中清除定时器和事件监听器,避免内存泄漏。 - 修正时间参数:将时长改为10分钟对应的毫秒数
600000。
内容的提问来源于stack exchange,提问作者etranz
相关产品推荐
相关产品推荐

