React:删除事件侦听器“beforeunload”不起作用

age*_*ntp 1 javascript reactjs

我试图在用户离开页面而不保存时添加提示。

这是我的代码:

    componentDidUpdate() {
        if (!this.props.data.get('is_data_saved')) {
            window.addEventListener('beforeunload', function(e) {
                e.returnValue = 'Data may not be saved'
            }, true);
        } else {
            window.removeEventListener('beforeunload', function(e) {
                e.returnValue = 'Data may not be saved'
            }, true);
            console.log('REMOVED')
        }
    }
Run Code Online (Sandbox Code Playgroud)

我在控制台中得到“已删除”,但即使已保存表单,仍然会弹出提示。是不是因为我把事件监听器放在了错误的组件中?

Gab*_*oli 5

我看到的基本问题是您正在添加和删除不同的功能。

您需要使用对现有方法的引用,而不是重写相同的代码。

beforeUnloadHandler(e){
    e.returnValue = 'Data may not be saved';
}
componentDidUpdate() {
    if (!this.props.data.get('is_data_saved')) {
        window.addEventListener('beforeunload', this.beforeUnloadHandler, true);
    } else {
        window.removeEventListener('beforeunload', this.beforeUnloadHandler, true);
        console.log('REMOVED')
    }
}
Run Code Online (Sandbox Code Playgroud)

但如果该组件以其他方式更新,最终可能会添加多个事件处理程序。为了避免这种情况,如果设置了事件处理程序,您也可以设置一个标志,或者更具防御性,始终先删除处理程序,然后在需要时重新添加它。

就像是

beforeUnloadHandler(e){
    e.returnValue = 'Data may not be saved';
}
componentDidUpdate() {
    // always remove the handler
    window.removeEventListener('beforeunload', this.beforeUnloadHandler, true);
    // if required add it back
    if (!this.props.data.get('is_data_saved')) {
        window.addEventListener('beforeunload', this.beforeUnloadHandler, true);
    }
}
Run Code Online (Sandbox Code Playgroud)