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

如何阻止浏览器返回跳转,直至用户确认window.confirm弹窗?

解决浏览器返回按钮确认后取消仍回退的问题

核心问题分析

  1. 原代码使用history.listen监听路由变化,该回调在路由跳转之后触发,无法阻止默认的回退行为,所以用户取消确认后页面已经完成跳转。
  2. isOnce变量定义在useEffect内部,每次usernameToSend变化都会重新初始化,无法跨渲染周期保持状态,导致重复弹窗问题。

修复方案

使用window.popstate事件(可阻止默认行为)+ useRef保存状态(跨渲染周期),同时手动控制历史栈状态:

import { useEffect, useRef } from 'react';

// 假设exitToServer已改为返回Promise的异步函数
// 如果未改,需要封装为Promise形式:
// const exitToServer = () => {
//   return new Promise((resolve) => {
//     // 原有HTTP请求逻辑,完成后调用resolve()
//     fetch('/api/exit', { method: 'POST', body: JSON.stringify({ username: usernameToSend }) })
//       .then(res => res.json())
//       .then(() => resolve())
//       .catch(() => resolve());
//   });
// };

useEffect(() => {
  const isProcessing = useRef(false); // 用useRef跨渲染保存状态

  const handlePopState = (e: PopStateEvent) => {
    if (!usernameToSend || isProcessing.current) return;

    e.preventDefault(); // 先阻止默认回退行为

    const shouldLeave = window.confirm("Leaving so soon? Chat data will be lost.");
    if (shouldLeave) {
      isProcessing.current = true;
      // 执行退出请求,完成后再触发回退
      exitToServer().finally(() => {
        window.history.goBack();
        // 请求完成后移除监听,避免后续触发
        window.removeEventListener('popstate', handlePopState);
      });
    } else {
      // 用户取消,手动将当前路径重新推入历史栈,恢复栈状态
      window.history.pushState(null, '', window.location.pathname);
      isProcessing.current = false;
    }
  };

  window.addEventListener('popstate', handlePopState);

  // 组件卸载或依赖变化时移除事件监听,防止内存泄漏
  return () => {
    window.removeEventListener('popstate', handlePopState);
  };
}, [usernameToSend]);

关键修改点说明

  • 改用popstate事件:该事件在浏览器回退行为触发前执行,可通过e.preventDefault()阻止默认跳转。
  • useRef保存状态:isProcessing的current属性会在组件整个生命周期内保持值,避免每次渲染重新初始化导致的重复弹窗。
  • 手动维护历史栈:用户取消时,调用history.pushState将当前路径重新加入历史栈,抵消popstate触发的栈弹出操作,确保页面停留在当前页。
  • 异步请求处理:等待exitToServer请求完成后再执行回退,避免请求未完成就跳转页面,同时请求完成后移除监听防止重复触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:24:55