発行:
更新:

ページ遷移

React Routerでページ遷移を実現する方法は、大きく分けて2つあります。

  1. <Link> コンポーネント - ユーザーがクリックして遷移する(宣言的な遷移)
  2. useNavigate フック - JavaScriptの処理として遷移する(命令的な遷移)

それぞれの使い方と使い分けを見ていきましょう。


Linkコンポーネントによる遷移

<Link> は、React Routerが提供する最も基本的なナビゲーションコンポーネントです。通常の <a> タグの代わりに使用します。

基本的な使い方

to プロパティに遷移先のパスを指定するだけで、SPAらしいスムーズなページ遷移が実現できます。

src/Navigation.jsx
import { Link } from "react-router-dom";

const Navigation = () => {
  return (
    <nav className="flex gap-4 p-4">
      <Link to="/" className="text-indigo-400 hover:text-indigo-300">
        ホーム
      </Link>
      <Link to="/about" className="text-indigo-400 hover:text-indigo-300">
        概要
      </Link>
      <Link to="/contact" className="text-indigo-400 hover:text-indigo-300">
        お問い合わせ
      </Link>
    </nav>
  );
};

通常の<a>タグとの違い

<a> タグを使うと、ブラウザはページ全体をリロードしてしまいます。一方、<Link> を使うと:

  • ページ全体のリロードが発生しない(SPAの利点)
  • 必要なコンポーネントだけが再レンダリングされる
  • ブラウザの「戻る・進む」ボタンが正しく動作する
  • アプリケーションの状態が保持される

スタイリングとアクティブ状態

現在のページに対応するリンクを強調表示したい場合は、NavLink コンポーネントを使うと便利です。

src/Navigation.jsx
import { NavLink } from "react-router-dom";

const Navigation = () => {
  return (
    <nav className="flex gap-4 p-4">
      <NavLink
        to="/"
        className={({ isActive }) =>
          isActive
            ? "text-white font-bold"
            : "text-indigo-400 hover:text-indigo-300"
        }
      >
        ホーム
      </NavLink>
      <NavLink
        to="/about"
        className={({ isActive }) =>
          isActive
            ? "text-white font-bold"
            : "text-indigo-400 hover:text-indigo-300"
        }
      >
        概要
      </NavLink>
    </nav>
  );
};

NavLinkclassName プロパティは関数を受け取ることができ、isActive という引数で現在のページかどうかを判定できます。


useNavigateフックによる遷移

<Link> コンポーネントはユーザーが「明示的にクリック」して遷移するためのものですが、プログラムの実行結果に応じて自動的に遷移させたい場合があります。
例えば、「ログイン処理が終わった」「フォームの保存が完了した」「一定時間経過した」といったタイミングです。

これらを実現するのが useNavigate フックです。

基本的な使い方

useNavigate を呼び出すと、ページを遷移させるための関数(navigate)を取得できます。

useNavigateフックの初期化と実行

関数コンポーネントのトップレベルでフックを呼び出し、イベントハンドラ内で実行するのが一般的なパターンです。

src/LoginPage.jsx
import { useNavigate } from "react-router-dom";

const LoginPage = () => {
  const navigate = useNavigate();

  const handleLogin = async () => {
    // 抽象化されたログイン処理
    const success = await authService.login();

    if (success) {
      // 成功したら、ダッシュボードへ遷移
      navigate("/dashboard");
    }
  };

  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold">ログイン</h1>
      <button
        onClick={handleLogin}
        className="mt-4 bg-indigo-600 px-4 py-2 rounded-lg"
      >
        ログインして移動
      </button>
    </div>
  );
};

高度な遷移制御

navigate 関数には、単なる移動以上の制御を行うためのオプションが用意されています。

履歴の置換 (replace)

通常、遷移するとブラウザの履歴スタックに新しいページが積まれます。しかし、ログイン完了後に「戻る」ボタンで再度ログイン画面に戻ってほしくない場合は、履歴を上書き(置換)します。

// 履歴スタックを積まず、現在のエントリを書き換える
navigate("/dashboard", { replace: true });

履歴の移動(相対的な移動)

数値(デルタ)を指定することで、履歴を前後に移動させることも可能です。

navigate(-1); // 1つ戻る(ブラウザの「戻る」ボタンと同じ挙動)
navigate(-2); // 2つ戻る

注意点と使い分け

3つの遷移方法の比較

React Routerには、用途に応じて3つの遷移方法があります。

1. <Link> / <NavLink> コンポーネント

使うべき場面: ユーザーがクリックして遷移する通常のリンク

<Link to="/about">概要ページへ</Link>
  • ナビゲーションメニュー
  • 記事一覧から詳細ページへのリンク
  • パンくずリスト
  • フッターのリンク集

2. useNavigate フック

使うべき場面: ユーザーの操作(クリック、サブミット)をきっかけに、JavaScriptの処理として遷移させたい時

const navigate = useNavigate();
const handleSubmit = async () => {
  await saveData();
  navigate("/success");
};
  • フォーム送信後のリダイレクト
  • ログイン成功後のダッシュボードへの遷移
  • ボタンクリック時の条件分岐による遷移
  • タイマーやイベントによる自動遷移

3. <Navigate> コンポーネント

使うべき場面: レンダリング時に即座にリダイレクトしたい時

if (!user) {
  return <Navigate to="/login" replace />;
}
  • 未ログインユーザーの強制リダイレクト
  • 権限のないページへのアクセス制御
  • 古いURLから新しいURLへの自動転送

基本的な選択ルール

  1. まずは <Link> を検討する - ユーザーがクリックするものは基本的にこれ
  2. 処理の後に遷移するなら useNavigate - フォーム送信、API呼び出しの後など
  3. 条件によって即座にリダイレクトするなら <Navigate> - 認証チェック、権限チェックなど

用途に合わせてこれらを適切に使い分けることで、ユーザーにとって違和感のない遷移フローを構築できます。

更新履歴

  • 2025-01-04 : <Link>タグを使ったページ遷移の基本説明を追加しました。