Reputation: 435
In my web application, I want to prompt user when he/she tries to close the browser/tab based upon Redux state using event handlers.
I am using the below code to prompt user before exiting based upon 'isLeaving' state.
function mapStateToProps(state) {
const {isLeaving} = state.app.getIn(['abc']);
return {
isLeaving
};
}
@connect(mapStateToProps, {}, undefined, {withRef: true})
export default class MyClass extends React.component {
@autobind
stayOnPage(event) {
if (this.props.isLeaving) {
const message = 'Are you sure you want to leave';
event.returnValue = message;
return message;
}
return false;
}
componentDidMount() {
window.addEventListener('beforeunload', (event) => {
this.stayOnPage(event);
});
}
componentWillUnmount() {
window.removeEventListener('beforeunload', (event) => {
this.stayOnPage(event);
});
}
componentWillReceiveProps(nextProps) {
if (this.props.prop1 !== nextProps.prop2) {
// do something
}
}
render() {
//
}
}
This code works fine. But whenever there is a change in prop1, I see that this.props.isLeaving does not have updated value.
Can somebody help? What is I'm doing wrong here?
Upvotes: 0
Views: 836
Reputation: 106
You aren't cleaning up correctly in componentWillUnmount. The event handler you're trying to remove is a brand new function closure, not the same instance that you added. You should just attach the actual handler, rather than using an arrow function, like so:
componentDidMount() {
window.addEventListener('beforeunload', this.stayOnPage);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.stayOnPage);
}
Possibly what you are seeing is the event triggering on a stale component instance, so it has old state.
Upvotes: 1
Reputation: 5770
React uses synthetic events, basically events are recycled to be more performant. You can read more on that here
What I normally do is pass the value I need on invocation
Not sure if this will work in your specific case because I define my event handlers in JSX instead of accessing the window
object (which you might want to do as well but to be honest I'm not sure) but I use this pattern all the time to handle e.target.value
properly
Upvotes: 0