React Router 6のガイド

React Routerは、Reactにおいてシングルページアプリケーション（SPA）のルーティングを実現するための標準的なライブラリです。

この記事では、React Routerの最新バージョンであるバージョン6に焦点を当て、その基本的な使い方から応用技術までを解説します。

## 1. React Routerの導入

React Routerをプロジェクトに導入するには、まずnpmまたはyarnを使用して `react-router-dom` パッケージをインストールします。

```bash
npm install react-router-dom
# または
yarn add react-router-dom
```

## 2. 基本的なルーティング

React Routerを使用する最も基本的な形は、BrowserRouterとRoutes、Routeコンポーネントを組み合わせることです。

以下は、基本的なルーティングの設定例です。

```jsx
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
import NoMatch from './NoMatch';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="*" element={<NoMatch />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;
```

**解説:**

BrowserRouterは、HTML5のhistory APIを利用するRouterです。

Routesは、子にRouteを持ち、どのルートにどのコンポーネントを割り当てるかを定義します。

RouteのpathプロパティでURLを指定し、elementプロパティでレンダリングするコンポーネントを指定します。

`path="*"` のルートは、定義されたいずれのパスにもマッチしない場合に使用されるワイルドカードです。

## 3. ネストされたルーティング

React Router 6では、ルートのネストが簡単になりました。

コンポーネント内部でRoutesを使用し、子ルートを定義することができます。

```jsx
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Layout from './Layout';
import Home from './Home';
import About from './About';
import NoMatch from './NoMatch';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="*" element={<NoMatch />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

export default App;
```

**解説:**

Layoutコンポーネントは、ホームページとアバウトページで共通のレイアウト（例えばナビゲーションバーなど）を提供します。

indexプロパティは、親ルートのパス（この場合は"/"）と完全に一致するURLにレンダリングされるコンポーネントを指定します。

## 4. プログラマティックなナビゲーション

リンクをクリックする代わりに、プログラムによってナビゲーションを制御することも可能です。これにはuseNavigateフックを使用します。

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

function HomeButton() {
  let navigate = useNavigate();
  function handleClick() {
    navigate('/home');
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
```

**解説:**

useNavigateフックは、ナビゲーション関数を提供します。

navigate関数にパスを渡すことで、アプリケーション内の指定されたパスに遷移します。

## 5. ルートの保護（認証）

アプリケーションにおいて特定のページを保護し、認証が必要なページへのアクセスを制御するには、ルートガードを使用します。

```jsx
import { Navigate } from 'react-router-dom';

function ProtectedRoute({ children }) {
  const auth = useAuth();  // 認証状態を管理するフック
  return auth ? children : <Navigate to="/login" replace />;
}
```

**解説:**

ProtectedRouteは、子コンポーネントを受け取り、認証状態authに応じてアクセスを制御します。

認証されていない場合、Navigateコンポーネントを使用してログインページにリダイレクトします。

## 6. 動的ルートマッチング

パラメータ化されたルートを設定して、動的なURL構造を扱う方法を学びます。

```jsx
<Route path="profile/:userId" element={<UserProfile />} />
```

**解説:**

:userIdは動的セグメントで、この部分には任意の値が入ります。
URLのこの部分をuseParamsフックを使って取得することができます。

```jsx
import { useParams } from 'react-router-dom';

function UserProfile() {
  let { userId } = useParams();
  return <h2>User ID: {userId}</h2>;
}
```

## 7. ラズベリーのリダイレクトと404ページ

ユーザーが存在しないページにアクセスした時のリダイレクトや、カスタム404ページの設定方法を解説します。

```jsx
<Route path="*" element={<NoMatch />} />
```

**解説:**

NoMatchコンポーネントは、存在しないルートに対して表示される404エラーページです。
ユーザーを別のページに自動的にリダイレクトさせたい場合は、Navigateコンポーネントを使用します。

## 8. 高度なネストルーティング

複雑なアプリケーションにおいて、ネストされたルーティングを効果的に管理する方法を紹介します。

```jsx
<Route path="dashboard" element={<DashboardLayout />}>
  <Route index element={<DashboardHome />} />
  <Route path="settings" element={<DashboardSettings />} />
</Route>
```

**解説:**

DashboardLayoutは、ダッシュボード関連のページに共通のレイアウトを提供します。
indexプロパティは、DashboardLayoutの基本パス（この場合は"/dashboard"）に対応します。

## 9. フックの利用

React Router 6で導入されたフックの中から主要なものを詳しく見ていきます。

- **useNavigate**

ナビゲーションをプログラム的に制御します。

- **useParams**

ルートパラメータを取得します。

- **useLocation**

現在のURLのlocationオブジェクトを取得します。

- **useRoutes**

動的ルート構成を可能にします。

##10. ルートの遅延読み込み

大規模アプリケーションのパフォーマンス向上のために、コード分割と遅延読み込みを実装する方法です。

```jsx
const About = React.lazy(() => import('./About'));

function App() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="about" element={<About />} />
      </Routes>
    </React.Suspense>
  );
}
```

**解説:**

React.lazyとReact.Suspenseを使用して、コンポーネントの遅延読み込みを行います。
これにより、初期ロード時のJavaScriptのファイルサイズを削減し、パフォーマンスを向上させることができます。