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?
How can I remove the beforeunload
event on other pages?
The beforeunload event is fired when the window, the document and its resources are about to be unloaded. The document is still visible and the event is still cancelable at this point. This event enables a web page to trigger a confirmation dialog asking the user if they really want to leave the page.
The onbeforeunload event occurs when the document is about to be unloaded. This event allows you to display a message in a confirmation dialog box to inform the user whether he/she wants to stay or leave the current page. The default message that appears in the confirmation box, is different in different browsers.
The componentWillUnmount() method allows us to execute the React code when the component gets destroyed or unmounted from the DOM (Document Object Model). This method is called during the Unmounting phase of the React Life-cycle i.e before the component gets unmounted.
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
:
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
You can abstract the beforeunload
event handling to a custom hook with the useRef
, and useEffect
hooks.
The custom hook useUnload
receives a function (fn
) and assigns it to the current ref. It calls useEffect
once (on component mount), and sets the event handler to be an anonymous function that will call cb.current
(if it's defined), and returns a cleanup function to remove the event handler, when the component is removed.
import { useRef, useEffect } from 'react';
const useUnload = fn => {
const cb = useRef(fn); // init with fn, so that type checkers won't assume that current might be undefined
useEffect(() => {
cb.current = fn;
}, [fn]);
useEffect(() => {
const onUnload = (...args) => cb.current?.(...args);
window.addEventListener("beforeunload", onUnload);
return () => window.removeEventListener("beforeunload", onUnload);
}, []);
};
export default useUnload;
Usage:
const MyComponent = () => {
useUnload(e => {
e.preventDefault();
e.returnValue = '';
});
return (
<div>
Some content
</div>
);
};
Ori's solution didn't work for me. I had to do this to make it work... (Thank you docs)
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With