React Router
1. React Routerとは?
React Routerは、Reactアプリケーションにルーティング機能を提供するライブラリです。
ルーティングとは、異なるビュー(画面)間の遷移を処理することを指します。
React RouterはReactアプリケーションにおける標準的なルーティングライブラリであり、以下の機能を可能にします:
- シングルページアプリケーション(SPA)内での複数ページの作成
- URLパラメータやクエリ文字列の処理
- ブラウザ履歴とナビゲーションの管理
- ネストされたルート(Nested Routes)とレイアウトの作成
- 認証のための保護されたルートの実装
ルーターがない場合、Reactアプリケーションは単一のページに制限され、異なるビュー間を移動する手段がなくなってしまいます。
2. React Routerのインストール
コマンドラインでプロジェクトのディレクトリに移動し、以下のコマンドを実行してパッケージをインストールします:
npm install react-router-dom3. BrowserRouterによるアプリケーションのラップ
ルーティングを有効にするには、アプリケーション全体を BrowserRouter コンポーネントでラップする必要があります:
function App() {
return (
<BrowserRouter>
{/* アプリケーションのコンテンツ */}
</BrowserRouter>
);
}4. ビュー(ページ)の作成
ルーティングを実演するために、アプリケーション内に「Home」「About」「Contact」の3つのページ(ビュー)を作成します。
ここでは簡略化のためにすべてのビューを同じファイル内に作成しますが、もちろん別々のファイルに分割することも可能です。
function Home() {
return <h1>ホーム画面</h1>;
}
function About() {
return <h1>アバウト画面</h1>;
}
function Contact() {
return <h1>お問い合わせ画面</h1>;
}5. 基本的なルーティング
React Routerでは、基本的なルーティングに主に3つのコンポーネントを使用します:
- Link: URLを更新するナビゲーションリンクを作成します
- Routes: すべてのルート定義を格納するコンテナです
- Route: URLパスとコンポーネントのマッピングを定義します
各リンクに対応するナビゲーションリンクとルートを追加してみましょう:
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function Home() {
return <h1>ホーム画面</h1>;
}
function About() {
return <h1>アバウト画面</h1>;
}
function Contact() {
return <h1>お問い合わせ画面</h1>;
}
function App() {
return (
<BrowserRouter>
{/* ナビゲーション */}
<nav>
<Link to="/">ホーム</Link> |{" "}
<Link to="/about">アバウト</Link> |{" "}
<Link to="/contact">お問い合わせ</Link>
</nav>
{/* ルート設定 */}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}この例のポイント:
BrowserRouterがアプリをラップし、ルーティング機能を有効にします。Linkコンポーネントがナビゲーションリンクを作成します。RoutesとRouteがルーティングの設定を定義します。
6. ネストされたルート (Nested Routes)
Route の中に別の Route を配置することができ、これを「ネストされたルート」と呼びます。
ネストされたルートを使用すると、新しいURLに移動した際、ページの一部のみを変更し、他の部分は変更や再読み込みをさせないようにできます。これは、ページの中にさらにページがあるような構造です。
上記の例に、Products コンポーネントの中でレンダリングされる2つの新しいコンポーネント CarProducts と BikeProducts を追加してみましょう。
import { BrowserRouter, Routes, Route, Link, Outlet } from 'react-router-dom';
function Home() {
return <h1>ホーム画面</h1>;
}
function Products() {
return (
<div>
<h1>製品ページ</h1>
<nav style={{ marginBottom: '20px' }}>
<Link to="/products/car">車</Link> |{" "}
<Link to="/products/bike">バイク</Link>
</nav>
{/* 子ルートのコンテンツがここにレンダリングされる */}
<Outlet />
</div>
);
}
function CarProducts() {
return (
<div>
<h2>車</h2>
<ul>
<li>アウディ</li>
<li>BMW</li>
<li>ボルボ</li>
</ul>
</div>
);
}
function BikeProducts() {
return (
<div>
<h2>バイク</h2>
<ul>
<li>ヤマハ</li>
<li>スズキ</li>
<li>ホンダ</li>
</ul>
</div>
);
}
function Contact() {
return <h1>お問い合わせ画面</h1>;
}
function App() {
return (
<BrowserRouter>
{/* ナビゲーション */}
<nav>
<Link to="/">ホーム</Link> |{" "}
<Link to="/products">製品情報</Link> |{" "}
<Link to="/contact">お問い合わせ</Link>
</nav>
{/* ルート設定 */}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products" element={<Products />}>
{/* 子ルートの定義 */}
<Route path="car" element={<CarProducts />} />
<Route path="bike" element={<BikeProducts />} />
</Route>
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}この例に関する重要な注意点:
- Outlet:
Productsコンポーネント内の<Outlet />要素は、子ルートのコンテンツをどこにレンダリングするかを指定します。 - Routes:
Routes要素内では、CarProductsとBikeProductsへのルートが、親であるProductsルートの子として含まれています。 - URL構造: URL構造は親ルートのパスに対して相対的になります。
/products/carに移動すると、CarProductsコンポーネントがレンダリングされます。/products/bikeに移動すると、BikeProductsコンポーネントがレンダリングされます。
7. アクティブなリンクのスタイリング
Link コンポーネントの特別なバージョンとして、リンクのURLが現在「アクティブ」かどうかを判別できる NavLink があります。NavLink は特に以下のケースで有用です:
- ナビゲーションメニュー
- パンくずリスト
- タブ
現在のURLが to プロパティと一致する場合、その NavLink はアクティブであると見なされます。これを利用して、アクティブなリンクにスタイルを適用しやすくなります。
import { BrowserRouter, Routes, Route, NavLink } from 'react-router-dom';
// アクティブなリンク用のスタイル関数
const navLinkStyles = ({ isActive }) => ({
color: isActive ? '#007bff' : '#333',
textDecoration: isActive ? 'none' : 'underline',
fontWeight: isActive ? 'bold' : 'normal',
padding: '5px 10px'
});
function Home() {
return <h1>ホーム画面</h1>;
}
function About() {
return <h1>アバウト画面</h1>;
}
function Contact() {
return <h1>お問い合わせ画面</h1>;
}
function App() {
return (
<BrowserRouter>
{/* アクティブ時にスタイルを適用するNavLinkを使用したナビゲーション */}
<nav style={{ marginBottom: '20px' }}>
<NavLink to="/" style={navLinkStyles}>ホーム</NavLink> |{" "}
<NavLink to="/about" style={navLinkStyles}>アバウト</NavLink> |{" "}
<NavLink to="/contact" style={navLinkStyles}>お問い合わせ</NavLink>
</nav>
{/* ルート設定 */}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}8. URLパラメータ
URLパラメータは、ルートパスに追加できる変数です。これらは、コンポーネント間でデータを渡す際によく使用されます。
例えば、パス http://localhost:5173/customer/Tobias において、URLパラメータは Tobias です。
URLパラメータを使用すると、URLの一部が変化する動的なルートを作成できます。URL内の変数のようだと考えると分かりやすいでしょう。
React Routerは、コンポーネント内でこれらのパラメータにアクセスするための useParams フックを提供しています。
以下は、異なる顧客名に対して挨拶を表示するシンプルなページの例です:
import { BrowserRouter, Routes, Route, Link, useParams } from 'react-router-dom';
function Info() {
// useParamsフックでURLパラメータを取得
const { firstname } = useParams();
return <h1>こんにちは、{firstname}さん!</h1>;
}
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/customer/Emil">Emil</Link> |
<Link to="/customer/Tobias">Tobias</Link> |
<Link to="/customer/Linus">Linus</Link>
</nav>
<Routes>
{/* :firstname がURLパラメータとして定義される */}
<Route path="/customer/:firstname" element={<Info />} />
</Routes>
</BrowserRouter>
);
}この例のポイント:
- ルートパス内の :
firstnameがURLパラメータです。 /customer/Emilにアクセスすると、「こんにちは、Emilさん!」と表示されます。/customer/Tobiasにアクセスすると、「こんにちは、Tobiasさん!」と表示されます。- URLには任意の名前を使用でき、挨拶が機能します!
http://localhost:5173/customer/Johnなどを試してみてください。