如何使用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
相关产品推荐
相关产品推荐

