I have a react component like :
import React, { PropTypes, Component } from \'react\'
class MyComponent extends Component {
componentDidMount() {
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
, and sets the event handler, 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 = cb.current;
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
}