Javascript reactjs 事件监听器 beforeunload 添加但未删除
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39094138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
reactjs event listener beforeunload added but not removed
提问by gamer
I have a react component like :
我有一个反应组件,如:
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
Here event lister is added to the component. When I refresh the page it gives me pop up asking to leave the page.
这里事件列表器被添加到组件中。当我刷新页面时,它让我弹出要求离开页面。
But when I go to another page and do refresh it again shows the same pop-up.
但是当我转到另一个页面并再次刷新时,它会显示相同的弹出窗口。
I am removing the eventListener
from the component on componentWillUnmount
. Then why it is not being removed?
我正在eventListener
从组件中删除componentWillUnmount
。那为什么不删除呢?
How can I remove the beforeunload
event on other pages?
如何删除beforeunload
其他页面上的事件?
回答by Ori Drori
The removeEventListener
should get the reference to the same callback that was assigned in addEventListener
. Recreating the function won't do. The solution is to create the callback elsewhere (onUnload
in this example), and pass it as reference to both addEventListener
and removeEventListener
:
本removeEventListener
应该得到的引用到在分配相同的回调addEventListener
。重新创建该函数是行不通的。解决方案是在别处创建回调(onUnload
在本例中),并将其作为对addEventListener
和 的引用传递removeEventListener
:
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
React hooks
反应钩子
You can abstract the beforeunload
event handling to a custom hook with the useRef
, and useEffect
hooks.
您可以beforeunload
使用useRef
, 和useEffect
挂钩将事件处理抽象为自定义挂钩。
The custom hook useUnload
receives a function (fn
) and assigns it to the current ref. It calls useEffect
, and sets the event handler, and returns a cleanup function to remove the event handler, when the component is removed.
自定义钩子useUnload
接收一个函数 ( fn
) 并将其分配给当前的 ref。useEffect
当组件被移除时,它调用,并设置事件处理程序,并返回一个清除函数来移除事件处理程序。
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;
Usage:
用法:
const MyComponent = () => {
useUnload(e => {
e.preventDefault();
e.returnValue = '';
});
return (
<div>
Some content
</div>
);
};
回答by Michael
Ori's solution didn't work for me. I had to do this to make it work... (Thank you docs)
Ori 的解决方案对我不起作用。我必须这样做才能使其正常工作......(谢谢文档)
componentDidMount() {
window.addEventListener('beforeunload', this.handleLeavePage);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.handleLeavePage);
}
handleLeavePage(e) {
const confirmationMessage = 'Some message';
e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
return confirmationMessage; // Gecko, WebKit, Chrome <34
}