EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

Reactでのページ離脱時のメッセージ表示について

現在Reactで管理画面系のフォームを作っているのですが、少しややこしい画面構成 + 使う人のリテラシーが高くない、という状態なので、フォームをsubmitせずにページ離脱しようとした場合、確認メッセージを表示しようということになりました。

画面遷移時の確認メッセージ表示は、beforeunloadイベントを使えば実現できそうです。

developer.mozilla.org

上記ページに従うと、Reactで使うためにはuseEffectを使って、クラスで言うcomponentDidMountのタイミングでaddEventListener、componentWillUnmountのタイミングでremoveEventListenerを実行すると良さそうです。 add時とremove時に同じ関数の実体を渡す必要があるので、

  const handleBeforeUnloadEvent = (event) => {
    event.preventDefault();
    event.returnValue = "";
  };

  useEffect(() => {
    window.addEventListener("beforeunload", handleBeforeUnloadEvent, true);
    return () => window.removeEventListener("beforeunload", handleBeforeUnloadEvent, true);
  }, []);

でできそうです。

さらに、フォームのsubmit時は画面遷移の確認メッセージは出したくないので、onSubmitの最後に

  const handleSubmit = (e) => {
    // validate + confirm処理
    …
    window.removeEventListener("beforeunload", handleBeforeUnloadEvent, true);
  }

としてみたのですが、submitすると確認メッセージが表示されてしまいます。

上で書いたように、add時とremove時は同じ関数の実体を渡す必要があると理解しているので、実体が違うのかな?でもどうすれば同じものを渡せるのかな?と試行錯誤していたのですが、以下の記事でuseCallbackフックというのを見つけました。

blog.uhy.ooo

で、これを使ってはじめの関数定義を

  const handleBeforeUnloadEvent = useCallback((event: BeforeUnloadEvent): void => {
    event.returnValue = "";
  },[]);

としてみたところ、無事submit時はメッセージが表示されなくなりました!

いやあ、Reactって奥が深いというか知らないことが多いというか仕様がややこしいというか…。でも動くとうれしいですね!