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

发布于:2025-02-11 ⋅ 阅读:(39) ⋅ 点赞:(0)

文章目录

封装hook

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

import useWindowBeforeUnload from '@/hooks/useWindowBeforeUnload';

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

  return (
    <div>
      {renderPrompt()}
    </div>
  );
}


网站公告

今日签到

点亮在社区的每一天
去签到