react-use 之 useBeforeUnload:在 React 中拦截页面刷新与关闭的 Side-effect Hook 实战指南
react-use 之 useBeforeUnload在 React 中拦截页面刷新与关闭的 Side-effect Hook 实战指南【免费下载链接】react-useReact Hooks — 项目地址: https://gitcode.com/gh_mirrors/re/react-use本文围绕 react-use 中的useBeforeUnloadHook 展开介绍如何通过一行式声明在 React 组件里监听浏览器的beforeunload事件在用户尝试刷新页面或关闭标签页时弹出离开确认提示常用于表单未保存提醒、编辑状态保护等场景。读完本文你将掌握布尔值与函数两种启用方式的完整用法、参数默认值与底层源码实现原理并能在实际项目中正确规避函数引用频繁变化带来的监听器重复注册问题。useBeforeUnload是 react-use 提供的Side-effect Hooks之一见 Side-effects.md其职责非常聚焦当用户尝试重新加载或关闭页面时通过浏览器原生beforeunload事件触发确认弹窗防止未保存的数据意外丢失。它已在 入口文件 中统一导出可直接从react-use包引入使用。基本用法布尔值开关最直观的用法是传入一个布尔值作为开关。当为true时页面会被武装用户刷新或关闭页面将触发浏览器确认框为false时则完全静默。import {useBeforeUnload} from react-use; const Demo () { const [dirty, toggleDirty] useToggle(false); useBeforeUnload(dirty, You have unsaved changes, are you sure?); return ( div {dirty pTry to reload or close tab/p} button onClick{() toggleDirty()}{dirty ? Disable : Enable}/button /div ); };上述示例中useToggle(false)来自同仓库的 useToggle.ts返回[state, toggle]toggle无参调用时取反、传入布尔值时直接赋值用来维护是否有未保存修改的dirty状态点击按钮开启后页面会显示提示文案此时刷新或关闭标签页浏览器会弹出离开确认再次点击按钮关闭后事件监听随即移除页面恢复可无打扰关闭。该用法与 stories/useBeforeUnload.story.tsx 中的Demo (boolean)演示完全一致可以直接在 Storybook 中交互体验。函数式启用动态判断是否拦截某些场景下是否拦截依赖实时计算的状态此时可以传入一个返回布尔值的函数。useBeforeUnload会在事件触发时调用该函数依据返回值决定是否弹出确认。import {useBeforeUnload} from react-use; const Demo () { const [dirty, toggleDirty] useToggle(false); const dirtyFn useCallback(() { return dirty; }, [dirty]); useBeforeUnload(dirtyFn, You have unsaved changes, are you sure?); return ( div {dirty pTry to reload or close tab/p} button onClick{() toggleDirty()}{dirty ? Disable : Enable}/button /div ); };需要注意每次dirtyFn引用变化都会重新注册事件回调源码见下文因此如果测试值变化频繁建议结合useCallback或 refs 稳定函数引用避免监听器被反复销毁重建。这一约束在原文档中已明确标注也是函数式用法与布尔式用法在工程上的核心差异。参数说明与默认值从 useBeforeUnload.ts 的函数签名可以看出完整的参数契约参数类型默认值说明enabledboolean \| (() boolean)true是否启用拦截传入函数时在每次事件触发时调用以其返回值作为最终判断依据messagestring \| undefinedundefined自定义确认提示文案会写入event.returnValueenabled省略时默认true即useBeforeUnload()裸调用也会直接启用页面离开拦截message可选。现代浏览器对自定义文案支持有限多数情况下仍会显示浏览器内置的通用提示但该参数仍建议按产品文案要求传入Hook 不返回任何值纯副作用使用时无需接收返回值。源码原理从事件监听到清理useBeforeUnload的实现非常精简核心逻辑完全依赖 React 的useCallback与useEffectuseBeforeUnload.tsconst useBeforeUnload (enabled: boolean | (() boolean) true, message?: string) { const handler useCallback( (event: BeforeUnloadEvent) { const finalEnabled typeof enabled function ? enabled() : true; if (!finalEnabled) { return; } event.preventDefault(); if (message) { event.returnValue message; } return message; }, [enabled, message] ); useEffect(() { if (!enabled) { return; } on(window, beforeunload, handler); return () off(window, beforeunload, handler); }, [enabled, handler]); };拆解其工作流程回调构造handler用useCallback缓存依赖[enabled, message]。当enabled是函数时每次事件触发都会调用它得到finalEnabled若为false则直接return不拦截事件拦截finalEnabled为真时调用event.preventDefault()并将message写入event.returnValue同时作为返回值返回——这正是beforeunload事件要求必须设置returnValue才能弹出确认框的经典写法监听注册useEffect在enabled为真时通过on(window, beforeunload, handler)注册监听卸载时调用off(window, beforeunload, handler)移除实现彻底的清理不会产生内存泄漏依赖与重注册useEffect依赖[enabled, handler]当enabled变化或handler因enabled/message变化而重建时监听会先移除再重新注册。这也从源码层面解释了函数式用法必须稳定函数引用的原因——若每次渲染都传新函数监听器将随每次渲染被销毁重建造成不必要的性能开销。其中on/off是 react-use 封装的跨环境事件绑定工具misc/util.ts内部会先判断目标对象是否存在addEventListener/removeEventListener方法再做绑定在 SSR 等无window环境下也能安全兜底。与 useToggle 的组合模式文档示例中反复出现的useToggle是 react-use 中与useBeforeUnload搭配最自然的兄弟 Hook。其实现基于useReduceruseToggle.tsconst toggleReducer (state: boolean, nextValue?: any) typeof nextValue boolean ? nextValue : !state;它支持两种调用方式不传参时切换布尔值传布尔值时强制设置为该值。在草稿编辑保护场景中通常用useToggle(false)初始化未修改状态在表单onChange时toggle(true)置脏提交成功后toggle(false)复位再配合useBeforeUnload(dirty)实现完整的离开拦截闭环。典型应用场景表单与编辑器防丢失内容已修改但未保存时启用拦截防止误刷新丢失草稿多步流程守卫向导式流程中途离开时提示用户当前进度会丢失自定义兜底判断当是否拦截依赖复杂条件如上传进行中、计时器运行中时用函数式写法在事件发生时实时求值。注意事项与浏览器行为边界拦截范围有限beforeunload只能拦截刷新、关闭标签页等导航行为无法拦截浏览器崩溃、断网等异常场景文案兼容性部分浏览器会忽略自定义returnValue文案仅显示通用提示因此不要依赖message承载关键信息函数引用稳定性函数式启用时务必用useCallback或 ref 稳定引用避免监听器频繁重建源码依赖分析见上文不要过度使用在不需要拦截的页面如已提交成功的回显页务必确保enabled为false或组件卸载以免给用户造成困扰框架层限制React 18 在部分场景对beforeunload事件处理有行为差异如遇异常建议在浏览器端直接验证原生事件行为再回归到 Hook 层排查。相关资源官方文档docs/useBeforeUnload.md源码实现src/useBeforeUnload.ts配套演示stories/useBeforeUnload.story.tsx含Demo (boolean)与Demo (function)两个 Story事件工具函数src/misc/util.tsSide-effect Hooks 分类索引docs/Side-effects.mdREADME 中的完整 Hook 列表README.md安装与运行本仓库的演示环境可参照 package.json 中的脚本yarn安装依赖后执行yarn storybook启动 Storybook默认端口 6008即可在 Side effects/useBeforeUnload 分组下直观体验上述两种用法。【免费下载链接】react-useReact Hooks — 项目地址: https://gitcode.com/gh_mirrors/re/react-use创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Laundary System 项目实战:用 Python 类实现洗衣服务客户管理与计费系统

Laundary System 项目实战:用 Python 类实现洗衣服务客户管理与计费系统

Laundary System 项目实战:用 Python 类实现洗衣服务客户管理与计费系统 【免费下载链接】Python My Python Examples 项目地址: https://gitcode.com/gh_mirrors/py/Python 本文以仓库 Laundary System/README.md 为核心,结合其配套源码 Laundary…

2026/9/22 0:34:38 阅读更多 →
安全实践与文档体系:深入解析 Security-101 课程中的安全策略、标准、基线、指南与规程

安全实践与文档体系:深入解析 Security-101 课程中的安全策略、标准、基线、指南与规程

安全实践与文档体系:深入解析 Security-101 课程中的安全策略、标准、基线、指南与规程 【免费下载链接】Security-101 8 Lessons, Kick-start Your Cybersecurity Learning. 项目地址: https://gitcode.com/GitHub_Trending/se/Security-101 本篇技术指南以…

2026/9/21 4:44:49 阅读更多 →
Ice 免费开源菜单栏管理上手:4 步装好并整理 Mac 菜单栏

Ice 免费开源菜单栏管理上手:4 步装好并整理 Mac 菜单栏

Ice 免费开源菜单栏管理上手:4 步装好并整理 Mac 菜单栏 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice Ice 是一款完全免费、GPL-3.0 开源协议的 Mac 菜单栏管理工具。它的核心职责很简…

2026/9/20 17:30:53 阅读更多 →

最新新闻

sprinkled报错速查手册:复制代码跑不通?3分钟定位问题

sprinkled报错速查手册:复制代码跑不通?3分钟定位问题

sprinkled报错速查手册:复制代码跑不通?3分钟定位问题 刚复制了一段Python数据处理代码,满怀期待地运行,结果控制台直接抛出一行让人懵圈的 NameError: name 'sprinkled' is not defined…

2026/9/22 3:54:19 阅读更多 →
搞定单步调试,让你的实战项目跑通不再靠猜

搞定单步调试,让你的实战项目跑通不再靠猜

搞定单步调试,让你的实战项目跑通不再靠猜 看了一堆教程,代码能跑,项目一写就崩,是不是你的常态?很多开发者卡在 实战项目 的最后一环:环境跑起来了,逻辑看似没问题,但一上生产环境或者复杂场景就报错。这时候,你需要的不是再刷十道算法题,而是真…

2026/9/22 3:54:19 阅读更多 →
在线公章制作生成免费实战:避开版本坑的3个最佳实践

在线公章制作生成免费实战:避开版本坑的3个最佳实践

在线公章制作生成免费实战:避开版本坑的3个最佳实践 版本升级后 API 全变了,导致原本跑得通的代码瞬间报错,这是很多开发者在接触电子印章或公章生成工具时最头疼的事。面对这种混乱,盲目尝试只会浪费时间,我们需要一套经过验证的最佳实践来快速定…

2026/9/22 3:54:19 阅读更多 →
面试突击:eeff原理图解与最佳实践,3招搞定高频考点

面试突击:eeff原理图解与最佳实践,3招搞定高频考点

面试突击:eeff原理图解与最佳实践,3招搞定高频考点 面试被问到 eeff 底层原理,你脑子里是不是瞬间一片空白?明明背过八股文,一碰到实际场景就卡壳,这种尴尬谁懂?别慌,今天咱们不整虚的,直接拆解 eeff…

2026/9/22 3:54:19 阅读更多 →
Go语言Web开发性能优化实战:一文搞懂从卡顿到丝滑

Go语言Web开发性能优化实战:一文搞懂从卡顿到丝滑

Go语言Web开发性能优化实战:一文搞懂从卡顿到丝滑 刚把 GitHub 上星数破万的 Go Web 项目代码复制下来, go run main.go 一敲,浏览器 F12 看着接口响应时间飙到 800ms,后端日志却显示 CPU…

2026/9/22 3:54:19 阅读更多 →
从零开始学编程避坑指南:5个致命错误让代码跑不通

从零开始学编程避坑指南:5个致命错误让代码跑不通

从零开始学编程避坑指南:5个致命错误让代码跑不通 刚学编程最崩溃的时刻,莫过于从网上复制一段“完美”代码,粘贴到编辑器里运行,结果直接报错。报错信息像天书一样滚过去,你盯着屏幕发呆,不知道是变量名拼错了,还是逻辑本身就有问题。这种“复制即崩…

2026/9/22 3:53:19 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →