reactjs イベント リスナー beforeunload が追加されましたが、削除されません 質問する

reactjs イベント リスナー beforeunload が追加されましたが、削除されません 質問する

次のような React コンポーネントがあります:

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他のページのイベントを削除するにはどうすればよいですか?

ベストアンサー1

removeEventListener、 で割り当てられた同じコールバックへの参照を取得する必要がありますaddEventListener。関数を再作成してもうまくいきません。解決策は、コールバックを別の場所 (この例では) に作成しonUnload、それをaddEventListenerと の両方への参照として渡すことです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

Reactフック

、およびフックをbeforeunload使用して、イベント処理をカスタム フックに抽象化できます。useRefuseEffect

カスタムフックはuseUnload関数(fn)を受け取り、それを現在の参照に割り当てます。これはuseEffect(コンポーネントのマウント時に)1回呼び出され、イベントハンドラを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>
  );
};

おすすめ記事