Skip to content

React Router v6 で前のページに戻る方法

React Router v6では、ナビゲーションの方法が以前のバージョンから変更されました。history.goBack() の代わりに、新しい useNavigate フックを使用する必要があります。

基本的な使用方法

useNavigate フックを使用すると、数値でナビゲーションの方向を指定できます:

jsx
import { useNavigate } from 'react-router-dom';

function App() {
  const navigate = useNavigate();

  return (
    <>
      <button onClick={() => navigate(-2)}>2ページ戻る</button>
      <button onClick={() => navigate(-1)}>戻る</button>
      <button onClick={() => navigate(1)}>進む</button>
      <button onClick={() => navigate(2)}>2ページ進む</button>
    </>
  );
}

戻る操作と代替ナビゲーション

戻る操作ができない場合(新しいタブで開かれたリンクなど)に備えて、代替のナビゲーション先を指定する方法があります:

jsx
import { useNavigate } from 'react-router-dom';

function NavigationComponent() {
  const navigate = useNavigate();
  
  const handleGoBack = () => {
    if ((window.history?.length && window.history.length > 1) || window.history.state?.idx) {
      navigate(-1);
    } else {
      navigate('/', { replace: true });
    }
  };

  return (
    <button onClick={handleGoBack}>
      戻るまたはホームへ
    </button>
  );
}

注意

window.history.state.idx の挙動はブラウザによって異なる場合があります。最新のブラウザでは動作しない可能性があるため、history.length を使用することをおすすめします。

React Router のみを使用した方法

window オブジェクトに依存せず、React Router の機能のみを使用する方法もあります:

jsx
import { useLocation, useNavigate } from 'react-router-dom';

function App() {
  const location = useLocation();
  const navigate = useNavigate();

  // 戻る操作が可能かどうかをチェック
  const canGoBack = location.key !== 'default';
  
  const handleNavigation = () => {
    if (canGoBack) {
      navigate(-1);
    } else {
      navigate('/', { replace: true });
    }
  };

  return (
    <button onClick={handleNavigation}>
      {canGoBack ? '戻る' : 'ホームへ'}
    </button>
  );
}

補足

location.key の値は初期ロケーションでは常に 'default' になります。この挙動を利用して、戻る操作が可能かどうかを判断できます。

明示的なナビゲーション状態の管理

認証処理などの特定のシナリオでは、履歴スタックに頼るのではなく、明示的にナビゲーション状態を管理する方が安全です:

jsx
import { useLocation, useNavigate } from 'react-router-dom';

// ログインページへのナビゲーション
function ProtectedComponent() {
  const location = useLocation();
  const navigate = useNavigate();
  const currentPath = location.pathname;
  
  const handleLoginRedirect = () => {
    navigate('/login', { state: { from: currentPath } });
  };
  
  // ...
}

// ログイン後のリダイレクト処理
function LoginComponent() {
  const location = useLocation();
  const navigate = useNavigate();
  
  const handleLoginSuccess = () => {
    const state = location.state;
    if (state?.from) {
      navigate(state.from); // 前のページにリダイレクト
    } else {
      navigate('/main-page'); // デフォルトページにリダイレクト
    }
  };
  
  // ...
}

Linkコンポーネントを使用する方法

ボタンではなくリンクを使用する場合は、Link コンポーネントでも同様のことができます:

jsx
import { Link, useLocation } from 'react-router-dom';

function BackLink() {
  const location = useLocation();
  const canGoBack = location.key !== 'default';
  const href = canGoBack ? -1 : '/';

  return (
    <Link to={href}>
      {canGoBack ? '戻る' : 'ホームへ'}
    </Link>
  );
}
型スクリプトを使用する場合

TypeScriptでは、Link コンポーネントに数値を渡すと型エラーが発生する可能性があります。この場合は navigate 関数を使用するか、型定義を拡張する必要があります。

まとめ

React Router v6では、前のページに戻る操作には useNavigate フックを使用します。基本的な使い方は navigate(-1) ですが、実際のアプリケーションでは戻る操作が可能かどうかを確認し、できない場合は代替のナビゲーションを提供することをおすすめします。

  • navigate(-1) - 1ページ戻る
  • navigate(1) - 1ページ進む
  • { replace: true } - 現在の履歴エントリを置き換える
  • 状態管理 - 複雑なナビゲーションには明示的な状態管理を使用する

これらのテクニックを組み合わせることで、ユーザーに快適なナビゲーション体験を提供できます。