【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>
  );
}
相关推荐
拖孩几秒前
微信群太多,管理麻烦?那试试接入AI助手吧~
前端·后端·微信
快起来别睡了7 分钟前
看完你就知道JavaScript 中的对象创建与继承方式原来这么简单?!
javascript
乌兰麦朵17 分钟前
Vue吹的颅内高潮,全靠选择性失明和 .value 的PUA!
前端·vue.js
Goodbaibaibai17 分钟前
创建一个简洁的Vue3 + TypeScript + Vite + Pinia + Vue Router项目
javascript·vue.js·typescript
Code季风17 分钟前
Gin Web 层集成 Viper 配置文件和 Zap 日志文件指南(下)
前端·微服务·架构·go·gin
蓝倾18 分钟前
如何使用API接口实现淘宝商品上下架监控?
前端·后端·api
舂春儿19 分钟前
如何快速统计项目代码行数
前端·后端
毛茸茸19 分钟前
⚡ 从浏览器到编辑器只需1秒,这个React定位工具改变了我的开发方式
前端
Pedantic20 分钟前
我们什么时候应该使用协议继承?——Swift 协议继承的应用与思
前端·后端
Software攻城狮21 分钟前
vite打包的简单配置
前端