フォーム入力中の離脱防止の重要性

Next.jsを使用したフォームでは、ユーザーが誤ってページを離れたりブラウザを閉じてしまうと、入力したデータが失われてしまいます。これを防ぐためには、離脱前に確認ダイアログを表示し、ユーザーに確認を促すことが有効です。この記事では、フォーム入力中の離脱防止を実装する方法を紹介します。

beforeunloadイベントでの離脱防止

ブラウザのbeforeunloadイベントを活用すると、ユーザーがページを閉じようとしたり、ブラウザバックを行う前に確認ダイアログを表示することができます。このイベントは、ユーザーが離脱を試みた際に発火し、ダイアログによって誤操作を防ぎます。

useEffect(() => {
  const handleBeforeUnload = (event) => {
    event.preventDefault();
    event.returnValue = '';  // 通常のブラウザではメッセージの変更は不可
  };
  window.addEventListener('beforeunload', handleBeforeUnload);
  return () => {
    window.removeEventListener('beforeunload', handleBeforeUnload);
  };
}, [isDirty]);  // isDirtyがtrueなら警告を表示

この実装により、入力が行われた状態でページを離脱する際に、確認を挟むことができます。

Next.jsuseRouterを使ったルート変更時のガード

Next.jsでは、useRouterフックを使ってルート変更を監視し、ページ遷移時に確認ダイアログを表示することも可能です。これは、ページ遷移によって入力データが消えてしまうのを防ぐために役立ちます。

import { useRouter } from 'next/router';
import { useEffect } from 'react';
const useFormGuard = (isDirty) => {
  const router = useRouter();
  useEffect(() => {
    const handleRouteChange = (url) => {
      if (isDirty && !window.confirm('入力内容は保存されていません。ページを離れますか?')) {
        // ルート変更をキャンセル
        router.events.emit('routeChangeError');
        throw 'routeChange aborted';
      }
    };
    router.events.on('routeChangeStart', handleRouteChange);
    return () => {
      router.events.off('routeChangeStart', handleRouteChange);
    };
  }, [isDirty]);
};

このコードでは、ルート変更時にユーザーに確認を促し、必要に応じて遷移をキャンセルすることができます。

状態管理とモーダルの実装

入力状態(例えばisDirty)を管理し、それに応じて確認ダイアログを表示する仕組みも重要です。状態が変化した際にモーダルを表示し、ユーザーにデータ破棄の確認を促すことで、誤ったページ遷移を防ぎます。

import { useState, useEffect } from 'react';
const [isDirty, setIsDirty] = useState(false);
// フォーム入力が行われたら、isDirtyをtrueに設定
const handleInputChange = () => setIsDirty(true);
// フォーム送信時にisDirtyをリセット
const handleSubmit = () => {
  setIsDirty(false);
};

確認モーダルは、MantineやChakra UIなどのUIライブラリを活用して実装できます。

まとめ

Next.jsでのフォーム入力中の離脱防止は、beforeunloadイベントやuseRouterを活用して実装できます。これにより、ユーザーのデータ損失を防ぎ、より安全で快適なフォーム体験を提供できるでしょう。実装する際には、フォームの入力状態(isDirty)を適切に管理し、必要なタイミングで確認を促すことが重要です。