React Router V6で共通レイアウトのようなことをやりたかったので、
調べて実装できたので、やり方のメモを残す。
結論:"Outlet"を使う
Outletを使うことで実装できます。
例えば、ヘッダー、メインコンテンツ、フッターという構成でメインコンテンツを切り替えたいとします。
ヘッダーとフッターを共通レイアウトとして、下記のような共通レイアウトコンポーネントを作成します。
Layout.tsx
import { FC } from "react"
//Outletをインポート
import { Outlet } from 'react-router-dom';
export const Layout: FC = () => {
return (
<>
<header>
ヘッダー
</header>
//ここが切り替わる
<Outlet />
<footer>
フッター
</footer>
</>
)
}
ポイントは、Outletの部分が切り替わるということです。
ルーティングは下記のように書きます。
index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// コンポーネントのインポート
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { About } from './components/About';
import { Contact } from './components/Contact';
const container = document.getElementById('app');
const root = createRoot(container!);
root.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Route>
</Routes>
</BrowserRouter>
</React.StrictMode>
);
LayoutのRouteで切り替えたいコンポーネントのRoute(メインコンテンツ)をネストします。
LayoutコンポーネントのOutletの部分がネストしたコンポーネントに置き換わる仕組みです。
余談:共通レイアウトを適応したくない場合
中には、共通レイアウトを適応させたくないページもあるでしょう。
それは簡単に実現できます。
例えば、Loginというコンポーネントがあるとしてそれには共通デザインが不要な場合は以下のように
LayoutのRouteの中にネストせず外側に書けばOKです。
index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// コンポーネントのインポート
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { About } from './components/About';
import { Contact } from './components/Contact';
const container = document.getElementById('app');
const root = createRoot(container!);
root.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<Layout />}>
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Route>
</Routes>
</BrowserRouter>
</React.StrictMode>
);
以上です。