発行:

レイアウトとネストされたルート

Webアプリケーションでは、「ヘッダーやナビゲーションバーは常に表示し、メインコンテンツ部分だけを切り替えたい」というケースが非常によくあります。
React Routerでは、 Nested Routes(ネストされたルート)Outlet コンポーネントを使って、この「入れ子」の構造をエレガントに解決します。

ルートレイアウトの作成

まず、アプリケーション全体の枠組みとなるレイアウトコンポーネントを作成します。

Outletの役割

Outlet は、「子ルートのコンテンツがレンダリングされる場所」を予約するためのコンポーネントです。親ルートのJSXの中に置くことで、どの場所に子要素を流し込むかを指定できます。

レイアウトコンポーネントの実装

以下は、ヘッダーとフッターを固定し、中央にコンテンツを表示する例です。

src/RootLayout.jsx
import { Link, Outlet } from "react-router-dom";

export const RootLayout = () => {
  return (
    <div className="min-h-screen bg-slate-950 text-white">
      {/* 共通ナビゲーション */}
      <nav className="border-b border-white/10 p-4 backdrop-blur-md">
        <div className="container mx-auto flex gap-6">
          <Link to="/" className="hover:text-indigo-400">Home</Link>
          <Link to="/about" className="hover:text-indigo-400">About</Link>
        </div>
      </nav>

      {/* 子ルートのコンテンツがここに入る */}
      <main className="container mx-auto py-8">
        <Outlet />
      </main>

      {/* 共通フッター */}
      <footer className="border-t border-white/10 p-8 text-center text-slate-500">
        &copy; 2026 DevFront 学習用サンプル
      </footer>
    </div>
  );
};

ルーティングのネスト(入れ子)定義

次に createBrowserRouter の定義を修正し、children プロパティを使って親子関係を作ります。

childrenプロパティによる階層構造

ルート定義を入れ子にすることで、URL構造(//about)とレイアウト構造を紐付けることができます。

src/main.jsx
const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />, // ここが親(枠組み)
    children: [
      {
        index: true, // パスが "/" の場合にデフォルトで表示
        element: <Home />,
      },
      {
        path: "about", // "/about" として扱われる(先頭の / は不要)
        element: <About />,
      },
    ],
  },
]);

indexルートの指定

index: true は非常に便利なプロパティです。親ルートのパスと完全に一致したときに、どのコンポーネントを Outlet に表示するかを決定します。

メリット:効率的な再描画

この手法を使う最大の利点は、 無駄な再描画(リレンダリング)がなくなること です。
ページを遷移しても RootLayout(ヘッダーやフッター)は破棄されず、Outlet の中身だけが交換されます。これにより、スクロール位置の状態保持や、共通パーツのアニメーションなどをスムーズに実現できます。