【React】刷新页面或跳转路由时进行二次确认

文章目录

封装hook

js 复制代码
import { useEffect, useRef } from 'react';
import { Prompt, useHistory, useLocation } from 'react-router-dom';

/**
 * 窗口关闭前提醒用户
 *
 * 参考:https://developer.mozilla.org/en-US/docs/Web/API/BeforeUnloadEvent
 */
export default function useWindowBeforeUnload(getMessage: () => string | undefined) {
  const location = useLocation();
  const history = useHistory();

  const ref = useRef({
    pathname: location.pathname,
  }).current;

  useEffect(() => {
    // 定义提示函数
    const promptBeforeUnload = (event: BeforeUnloadEvent) => {
      const message = getMessage();
      console.log('message before unload', message);

      if (!message) return;

      // 设置提示信息
      event.preventDefault();
      event.returnValue = message;
      return message;
    };

    // 监听 onbeforeunload 事件
    window.addEventListener('beforeunload', promptBeforeUnload);
    return () => window.removeEventListener('beforeunload', promptBeforeUnload);
  });

  //  hash 路由下存在问题,需要谨慎使用
  // 问题:跳转时如果取消了,路由依然会发生辩护,导致下次跳转相同路由,不会出现提示,且刷新页面会进入到目标页面
  const renderPrompt = () => (
    <Prompt
      when={!!getMessage()}
      message={(location, action) => {
        const message = getMessage();
        if (message) return `${message}(即将跳转:${location.pathname}${location.search})`;
        return false;
      }}
    />
  );

  return { renderPrompt };
}

使用hook

js 复制代码
import useWindowBeforeUnload from '@/hooks/useWindowBeforeUnload';

export default function () {
  const { renderPrompt } = useWindowBeforeUnload(() => {
    return '如果有未保存的修改,离开后将会丢失!';
  });

  return (
    <div>
      {renderPrompt()}
    </div>
  );
}
相关推荐
San30.5 小时前
深入理解浏览器渲染流程:从HTML/CSS到像素的奇妙旅程
前端·css·html
IT_陈寒5 小时前
5个Python 3.12新特性让你的代码效率提升50%,第3个太实用了!
前端·人工智能·后端
周杰伦_Jay5 小时前
【Python Web开源框架】Django/Flask/FastAPI/Tornado/Pyramid
前端·python·开源
艾小码6 小时前
为什么你的JavaScript代码总是出bug?这5个隐藏陷阱太坑了!
前端·javascript
辻戋8 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保8 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun9 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp9 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.10 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl12 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享