React项目Chrome环境下onbeforeunload事件始终无法触发该如何解决?
事件不触发的核心原因
- 事件名填写错误:
window.addEventListener注册事件时不需要加on前缀,你填写的onbeforeunload是错误的,正确的事件名是beforeunload,onpagehide、onunload同理注册时要去掉前缀写pagehide、unload,这是三个事件都无法触发的首要问题。 - Chrome浏览器的安全限制:
beforeunload事件中不允许执行alert、confirm、prompt等弹窗操作,你加的alert不会弹出,也不要随意调用ev.preventDefault(),除非你需要弹出用户确认离开的系统提示,自定义提示内容在新版Chrome中也已经被禁用,只会显示浏览器默认的离开提示。 - 生命周期使用错误:
componentWillMount已经在React16.3之后被废弃,该生命周期可能被调用多次,也可能在服务端渲染时执行,导致事件重复绑定或绑定失败。同时你需要在组件卸载时解绑事件,避免内存泄漏。 - this指向问题:你直接赋值
var handle = this.handleWindowClose,如果handleWindowClose没有提前绑定this,执行时内部的this会指向错误,导致逻辑执行失败。
修正后的类组件代码
// 方法用箭头函数定义,避免this指向问题 handleWindowClose = () => { const value = window.localStorage.getItem('tabs') if (value !== null) { const loc = +value window.localStorage.setItem('tabs', (loc - 1).toString()) } } componentDidMount() { // 注册事件用正确的事件名 beforeunload,不带on前缀 window.addEventListener('beforeunload', this.handleWindowClose) } componentWillUnmount() { // 组件卸载时解绑事件 window.removeEventListener('beforeunload', this.handleWindowClose) }
额外注意事项
- 不要在
beforeunload中执行耗时过长的同步操作,浏览器会直接终止执行,你目前的localStorage读写操作属于轻量同步操作,可以正常执行。 - 如果你使用的是React18函数组件,可以用以下写法绑定事件:
useEffect(() => { const handleWindowClose = () => { const value = window.localStorage.getItem('tabs') if (value !== null) { const loc = +value window.localStorage.setItem('tabs', (loc - 1).toString()) } } window.addEventListener('beforeunload', handleWindowClose) return () => { window.removeEventListener('beforeunload', handleWindowClose) } }, [])
内容的提问来源于stack exchange,提问作者Austin
相关产品推荐
相关产品推荐

