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

reactjs event listener beforeunload added but not removed

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

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

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

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

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

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

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

的引用传递
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 (如果它是 defined),并且 returns 进行清理删除事件处理程序的函数,当组件被删除时。

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 的解决方案对我不起作用。我必须这样做才能让它发挥作用...(感谢文档)

  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
  }

您可以使用以下钩子:

https://www.npmjs.com/package/react-beforeunload

示例:

import { Beforeunload } from 'react-beforeunload';

// ...

<Beforeunload onBeforeunload={(event) => event.preventDefault()}>
  <MyApp />
</Beforeunload>