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

如何使用react-beforeunload钩子?如何区分窗口刷新与关闭操作?

使用react-beforeunload钩子的方法

1. 安装依赖

首先安装对应的包:

npm install react-beforeunload
# 或
yarn add react-beforeunload

2. 两种使用方式

方式一:组件包裹式(适用于类组件或范围监听场景)

import { Beforeunload } from 'react-beforeunload';

function App() {
  const handleBeforeunload = (event) => {
    event.preventDefault();
    // 自定义离开提示(部分浏览器可能忽略此文本)
    event.returnValue = '确定要离开当前页面吗?';
  };

  return (
    <Beforeunload onBeforeunload={handleBeforeunload}>
      <div>你的应用内容</div>
    </Beforeunload>
  );
}

方式二:useBeforeunload钩子(推荐函数组件使用)

import { useBeforeunload } from 'react-beforeunload';

function App() {
  useBeforeunload((event) => {
    event.preventDefault();
    event.returnValue = '确定要离开当前页面吗?';
  });

  return <div>你的应用内容</div>;
}

区分窗口刷新与关闭操作执行logout函数

浏览器原生没有直接区分刷新和关闭窗口的API,因为beforeunload事件在刷新、关闭、页面跳转时都会触发。以下是几种可行的间接方案:

方案1:结合会话存储(sessionStorage)判断

利用sessionStorage刷新页面时保留、窗口关闭时清除的特性:

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    // 页面加载时检查标记:无标记说明上次是关闭窗口
    if (!sessionStorage.getItem('isRefreshing')) {
      logout();
    } else {
      // 刷新过来的,清除标记
      sessionStorage.removeItem('isRefreshing');
    }

    const handleBeforeunload = () => {
      sessionStorage.setItem('isRefreshing', 'true');
    };

    window.addEventListener('beforeunload', handleBeforeunload);
    return () => window.removeEventListener('beforeunload', handleBeforeunload);
  }, []);

  const logout = () => {
    // 你的logout逻辑,比如调用后端接口
    console.log('执行logout');
  };

  return <div>你的应用内容</div>;
}

注意:此方案是在页面重新加载时判断上次操作,无法在beforeunload触发时立即区分,适合允许延迟执行logout的场景。

方案2:监听用户交互标记刷新操作

通过键盘快捷键、右键菜单等行为标记刷新:

import { useState, useEffect } from 'react';
import { useBeforeunload } from 'react-beforeunload';

function App() {
  const [isRefresh, setIsRefresh] = useState(false);

  useEffect(() => {
    // 监听刷新快捷键(F5、Ctrl+R、Cmd+R)
    const handleKeydown = (e) => {
      if (e.key === 'F5' || (e.ctrlKey && e.key === 'r') || (e.metaKey && e.key === 'r')) {
        setIsRefresh(true);
      }
    };

    window.addEventListener('keydown', handleKeydown);
    return () => window.removeEventListener('keydown', handleKeydown);
  }, []);

  useBeforeunload(() => {
    if (!isRefresh) {
      // 非刷新操作,执行logout
      logout();
    }
    setIsRefresh(false);
  });

  const logout = () => {
    console.log('执行logout');
  };

  return <div>你的应用内容</div>;
}

缺点:无法覆盖所有刷新场景(比如点击地址栏刷新按钮),可靠性有限。

方案3:结合pagehide事件的persisted属性(移动端优先)

移动端浏览器中,pagehide事件的persisted为true表示页面被缓存(如后退),否则大概率是关闭窗口:

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    const handlePageHide = (event) => {
      if (!event.persisted) {
        logout();
      }
    };

    window.addEventListener('pagehide', handlePageHide);
    return () => window.removeEventListener('pagehide', handlePageHide);
  }, []);

  const logout = () => {
    console.log('执行logout');
  };

  return <div>你的应用内容</div>;
}

注意:桌面端浏览器区分度不高,仅作为补充方案。


内容的提问来源于stack exchange,提问作者Byoungmin Kang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:00:20