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

react-router-dom v6未导出useBlocker、usePrompt,如何实现页面离开提醒功能

React Router v6 实现页面离开提醒方案

方案1:v6.4+ 数据路由(Data Router)直接使用官方恢复的API

React Router 从v6.4版本开始,在createBrowserRouter/createHashRouter等数据路由模式下重新恢复了usePrompt和useBlocker两个API,可直接使用:

基础用法(usePrompt)

适合直接用浏览器默认提示框的场景:

import { usePrompt } from 'react-router-dom';

function EditPage() {
  // 第一个参数为提示文案,第二个参数为是否触发拦截的判断条件
  usePrompt(
    "你当前有未保存的修改,确定要离开吗?",
    true // 可替换为实际业务判断,比如表单是否被修改、是否有未提交内容等
  );

  return <div>编辑页面内容</div>
}

自定义弹框用法(useBlocker)

适合需要自定义拦截弹窗样式的场景:

import { useBlocker } from 'react-router-dom';

function EditPage() {
  // 传入拦截判断逻辑,返回true则触发拦截
  const blocker = useBlocker(
    ({ currentLocation, nextLocation }) => 
      currentLocation.pathname !== nextLocation.pathname && true // 替换为实际业务判断
  );

  // 拦截触发时渲染自定义弹窗
  if (blocker.state === "blocked") {
    return (
      <div className="confirm-modal">
        <p>你有未保存的修改,确定离开当前页面吗?</p>
        <button onClick={() => blocker.proceed()}>确定离开</button>
        <button onClick={() => blocker.reset()}>留在页面</button>
      </div>
    )
  }

  return <div>编辑页面内容</div>
}

方案2:非数据路由/低于v6.4版本自定义实现

如果你使用的是传统<BrowserRouter>组件式路由,或者v6.4以下的版本,可以自定义Hook实现同等效果:

import { useEffect, useCallback, useContext, useState } from 'react';
import { UNSAFE_NavigationContext as NavigationContext } from 'react-router-dom';

// 自定义页面离开拦截Hook
function useCustomPrompt(shouldBlock, tipMessage) {
  const { navigator } = useContext(NavigationContext);

  // 拦截浏览器刷新、关闭页面的场景
  const handleBeforeUnload = useCallback((e) => {
    if (!shouldBlock) return;
    e.preventDefault();
    e.returnValue = tipMessage;
    return tipMessage;
  }, [shouldBlock, tipMessage]);

  useEffect(() => {
    if (!shouldBlock) return;
    // 拦截React Router内部路由跳转的场景
    const unblock = navigator.block((transition) => {
      const confirmLeave = window.confirm(tipMessage);
      if (confirmLeave) {
        unblock();
        transition.retry();
      }
    });

    window.addEventListener('beforeunload', handleBeforeUnload);
    return () => {
      unblock();
      window.removeEventListener('beforeunload', handleBeforeUnload);
    };
  }, [shouldBlock, tipMessage, navigator, handleBeforeUnload]);
}

// 组件内使用示例
function EditPage() {
  // 示例:判断表单是否有未保存的修改
  const [formDirty, setFormDirty] = useState(false);
  // 调用自定义Hook传入拦截条件和提示文案
  useCustomPrompt(formDirty, "你有未保存的修改,确定离开吗?");

  return <div>编辑页面内容</div>
}

注意:自定义实现依赖的UNSAFE_NavigationContext虽然标了不安全标识,但属于React Router内部稳定使用的API,兼容性较好,同时覆盖了路由跳转、浏览器前进后退、刷新/关闭页面的所有拦截场景。

内容的提问来源于stack exchange,提问作者Nguyễn Tuấn Kiệt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:54:03