我有一个类似的反应成分:
import React, { PropTypes, Component } from 'react' class MyComponent extends Component { componentDidMount() { window.addEventListener("beforeunload", function (event) { console.log("hellooww") event.returnValue = "Hellooww" }) } componentWillUnmount() { window.removeEventListener("beforeunload", function (event) { console.log("hellooww") event.returnValue = "Hellooww" }) } render() { return ( <div> Some content </div> ) } } export default MyComponent
这里,事件列表器已添加到组件。当我刷新页面时,它弹出窗口要求离开页面。
但是当我转到另一个页面并刷新时,它再次显示相同的弹出窗口。
我正在eventListener从中删除组件componentWillUnmount。那为什么不将其删除呢?
eventListener
componentWillUnmount
如何删除beforeunload其他页面上的事件?
beforeunload
本removeEventListener应该得到的引用到在分配相同的回调addEventListener。重新创建该功能将无效。解决方案是在其他地方(onUnload在本示例中)创建回调,并将其作为对addEventListener和的引用传递removeEventListener:
removeEventListener
addEventListener
onUnload
import React, { PropTypes, Component } from 'react'; class MyComponent extends Component { onUnload = e => { // the method that will be used for both add and remove event e.preventDefault(); e.returnValue = ''; } componentDidMount() { window.addEventListener("beforeunload", this.onUnload); } componentWillUnmount() { window.removeEventListener("beforeunload", this.onUnload); } render() { return ( <div> Some content </div> ); } } export default MyComponent
您可以beforeunload使用useRef和useEffect钩子将事件处理抽象为自定义钩子。
useRef
useEffect
自定义钩子useUnload接收一个函数(fn)并将其分配给当前引用。它会调用useEffect,并设置事件处理程序,并在删除组件时返回清除函数以删除事件处理程序。
useUnload
fn
import { useRef, useEffect } from 'react'; const useUnload = fn => { const cb = useRef(fn); useEffect(() => { const onUnload = cb.current; window.addEventListener("beforeunload", onUnload); return () => window.removeEventListener("beforeunload", onUnload); }, [cb]); }; export default useUnload;
用法:
const MyComponent = () => { useUnload(e => { e.preventDefault(); e.returnValue = ''; }); return ( <div> Some content </div> ); };