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

ReactJS页面自动刷新后跳转新页面自动返回问题求助

解决页面自动刷新导致跳转后返回的问题

问题描述

我通过setTimeout/setInterval实现Page1页面自动刷新,但跳转到其他页面后,几秒后会自动返回Page1;同时,跳转Page3前需要用户确认的stopTest函数逻辑也失效。尝试过window.beforeunload事件监听、ReactuseBeforeUnload钩子均无效果。

问题根源

  1. 定时器未可靠清理:原代码中定时器或状态变量直接声明在组件外部,组件卸载时无法确保定时器被清除;beforeunload事件受浏览器限制,无法保证回调总能执行。
  2. 状态变量丢失:allowStateChange这类直接声明的变量,会在组件重渲染或卸载后丢失状态,无法有效控制刷新逻辑。
  3. a标签默认行为干扰:原stopTest中的a标签href="#"会触发锚点跳转,干扰window.location.href的正常跳转逻辑。

修复方案

核心修复点

  • 用useRef管理定时器和状态变量,确保组件生命周期内状态持久。
  • 在useEffect的清理函数中清除定时器,这是组件卸载时最可靠的清理时机。
  • 移除a标签的默认锚点行为,避免干扰跳转逻辑。

修复后的完整代码

import React, { useState, useEffect, useRef, useCallback } from 'react';
import axios from 'axios';

const SampleTestStats = () => {
  // 用useRef保存状态和定时器,避免组件重渲染丢失
  const allowStateChange = useRef(true);
  const refreshInterval = useRef(null);
  const SAMPLE_TEST_STATS_REFRESH_TIME = 3000;
  const [result, setResult] = useState([{ tid: 0, tcname: "none" }]);

  const user = JSON.parse(localStorage.getItem('user'));
    
  const fetchTestStats = async () => {
    try {
      const res = await axios.post(
        '/test/current/active/data', 
        { uid: user.uid, email: user.email },
        { headers: { 'Authorization': user.jwt } }
      );
      if (res.status === 200) {
        if (allowStateChange.current) {
          const newResult = { tid: res.data[0].tid, tcname: res.data[0].testname };
          setResult([newResult]);
        }
      }
    } catch (err) {
      console.error('获取测试数据失败:', err);
    }
  };

  useEffect(() => {
    fetchTestStats();
    // 设置自动刷新定时器
    refreshInterval.current = setInterval(() => {
      if (allowStateChange.current) {
        window.location.reload();
      }
    }, SAMPLE_TEST_STATS_REFRESH_TIME);

    // 组件卸载时强制清理定时器
    return () => {
      if (refreshInterval.current) {
        clearInterval(refreshInterval.current);
      }
    };
  }, []); 

  // 修复跳转确认逻辑,移除a标签干扰
  const stopTest = useCallback((tid) => {
    if (window.confirm(`您确定要停止测试吗?点击OK确认。`)) {
      allowStateChange.current = false;
      window.location.href = '/components/testbeds';
    }
  }, []);
  
  return (
    <div className="center">
      简易刷新测试页面,测试ID = {result[0].tid} 
      测试名称 = {result[0].tcname}.<br/> 
      停止测试 
      <span style={{ cursor: 'pointer', color: 'blue', textDecoration: 'underline' }} 
            onClick={() => stopTest(result[0].tid)}>
        点击这里
      </span>
      立即停止。
    </div> 
  );
};

export default SampleTestStats;

修复说明

  1. useRef持久化状态:allowStateChange和refreshInterval通过useRef存储,不会因组件重渲染重置,确保状态和定时器ID在组件生命周期内有效。
  2. useEffect清理定时器:组件卸载时,useEffect返回的清理函数会自动执行,彻底清除定时器,终止自动刷新逻辑。
  3. 移除a标签默认行为:将原a标签替换为span,避免锚点跳转干扰,确保stopTest的跳转逻辑正常执行。
  4. 跳转前标记状态:在stopTest中设置allowStateChange.current = false,即使定时器未完全清理,也不会触发刷新操作。

内容的提问来源于stack exchange,提问作者Kamal Palei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 01:11:09