You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS无活动10分钟自动登出功能异常排查

修复React用户无活动自动登出问题

你的代码存在几个核心问题,导致无论用户是否活跃都会强制登出:

  1. 定时器变量未持久化:用var timer声明的变量会在组件重渲染时丢失引用,导致无法正确清除旧定时器。
  2. 初始未启动定时器:只有用户触发事件后才会启动定时器,页面加载后若用户不操作,定时器永远不会触发。
  3. 事件监听清理不完整:组件卸载时未清理事件监听器和定时器,会引发内存泄漏。
  4. 时间参数错误:你写的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:05:54