添加但未删除 reactjs 事件侦听器 beforeunload

新手上路,请多包涵

我有一个像这样的反应组件:

 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

这里的事件列表器被添加到组件中。当我刷新页面时,它会弹出要求离开页面。

但是当我转到另一个页面并再次刷新时,它会显示相同的弹出窗口。

我正在从 eventListener 上的组件中删除 componentWillUnmount 。那为什么它没有被删除呢?

如何删除其他页面上的 beforeunload 事件?

原文由 gamer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 677
2 个回答

removeEventListener 应该获得对在 addEventListener 中分配的相同回调的引用。重新创建函数是行不通的。解决方案是在别处创建回调(本例中为 onUnload ),并将其作为对 addEventListenerremoveEventListener 8408 的引用传递

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

反应钩子

您可以使用 useRefuseEffect 挂钩将 beforeunload 事件处理抽象为自定义挂钩。

自定义挂钩 useUnload 接收一个函数( fn )并将其分配给当前 ref。它调用 useEffect 一次(在组件挂载时),并将事件处理程序设置为匿名函数,该函数将调用 cb.current (如果已 定义),并返回清理函数以删除事件处理程序,当组件被移除时。

 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;

用法:

 const MyComponent = () => {
  useUnload(e => {
    e.preventDefault();
    e.returnValue = '';
  });

  return (
    <div>
      Some content
    </div>
  );
};

原文由 Ori Drori 发布,翻译遵循 CC BY-SA 4.0 许可协议

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
  }

原文由 Michael 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题