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

如何在react-router-dom v6页面导航时处理beforeunload事件

React Router v6 客户端导航时触发状态保存逻辑

要在React Router v6的客户端导航(比如通过NavLink跳转)时执行状态保存API调用,你可以结合React Router的钩子和React的生命周期处理,同时保留原有的浏览器刷新/关闭处理逻辑,具体方案如下:

方案一:利用组件卸载的清理函数

当通过客户端路由离开当前页面组件时,组件会被卸载,此时可以通过useEffect的清理函数触发API调用:

import React from 'react';

const YourPageComponent = () => {
  // 假设这是需要保存的状态
  const [pageState, setPageState] = React.useState({});

  // 封装状态保存的API调用逻辑
  const saveState = async () => {
    try {
      await fetch('/api/save-latest-state', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(pageState)
      });
      console.log('状态已成功提交');
    } catch (error) {
      console.error('提交状态失败:', error);
    }
  };

  // 处理浏览器刷新/关闭的情况
  React.useEffect(() => {
    const handleBeforeUnload = () => {
      saveState();
    };
    window.addEventListener('beforeunload', handleBeforeUnload);
    return () => window.removeEventListener('beforeunload', handleBeforeUnload);
  }, [pageState]);

  // 处理客户端导航离开当前页面的情况(组件卸载时执行)
  React.useEffect(() => {
    return () => {
      saveState();
    };
  }, [pageState]);

  // 页面组件的其他逻辑和渲染
  return (
    <div>
      {/* 页面内容 */}
    </div>
  );
};

export default YourPageComponent;

方案二:拦截导航动作(支持确认提示)

如果需要在用户导航离开前添加确认提示,可以使用useNavigate的unblock方法拦截导航:

import React from 'react';
import { useNavigate } from 'react-router-dom';

const YourPageComponent = () => {
  const [pageState, setPageState] = React.useState({});
  const navigate = useNavigate();

  const saveState = async () => {
    try {
      await fetch('/api/save-latest-state', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(pageState)
      });
      console.log('状态已成功提交');
    } catch (error) {
      console.error('提交状态失败:', error);
    }
  };

  // 处理浏览器刷新/关闭
  React.useEffect(() => {
    const handleBeforeUnload = () => {
      saveState();
    };
    window.addEventListener('beforeunload', handleBeforeUnload);
    return () => window.removeEventListener('beforeunload', handleBeforeUnload);
  }, [pageState]);

  // 拦截客户端导航
  React.useEffect(() => {
    const unblockNavigation = navigate((location) => {
      // 可添加确认逻辑,比如:
      // const shouldLeave = window.confirm('确定要离开吗?未保存的内容会提交');
      // if (!shouldLeave) return false;

      // 执行状态保存
      saveState();
      // 允许导航继续
      return true;
    });

    // 组件卸载时解除拦截
    return () => unblockNavigation();
  }, [navigate, pageState]);

  return (
    <div>
      {/* 页面内容 */}
    </div>
  );
};

export default YourPageComponent;

关键说明

  • 两个方案都将pageState作为useEffect的依赖项,确保状态更新时,effect能获取到最新的状态值,避免闭包问题。
  • 方案一适合无需用户确认、自动保存状态的场景;方案二适合需要拦截导航并提示用户的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:15:59