概要
- Reactアプリケーションでページ遷移やルーティングを管理する React Router 6 の基本
-
createBrowserRouter
とRouterProvider
を用いた、現代的で型安全なルーティング構造 - 親子ルート構造(ネストルーティング) や エラーバウンダリ の基本的な使い方
React Router 6 によって 「URL に応じたコンポーネント描画、ページ遷移管理、エラーハンドリング」 がシンプルかつ型安全に実現できる
実施条件
- React + TypeScript プロジェクトが構築済みであること
- TypeScript での型定義の基本が理解できていること
- React コンポーネントの基本構造(関数コンポーネント、JSX)が理解できていること
環境
ツール | バージョン | 目的 |
---|---|---|
Node.js | 22.5.1 | Reactアプリ実行環境 |
React | 19.1.0 | UI構築 |
TypeScript | 4.9 | 型安全な開発 |
React Router | 6.14 | ルーティング管理 |
React Router 6 の基本構造
1. ディレクトリ構成例(最小構成)
src/
├── pages/
│ ├── HomeScreen/
│ │ └── HomeScreen.tsx
│ ├── IntroScreen/
│ │ └── IntroScreen.tsx
│ ├── FeatureA/
│ │ └── FeatureA.tsx
│ ├── FeatureB/
│ │ └── FeatureB.tsx
│ ├── xxx/
│ │ └── xxx.tsx
│ └── NotFound/
│ └── NotFound.tsx
├── App.tsx # トップレベルコンポーネント: ルート定義を直接記述
└── index.tsx # エントリーポイント: ReactDOM.createRootでApp.tsxをブラウザにマウント
- ページはすべて
pages/
に集約 - ルーター定義は
App.tsx
に直接記述 - ネストルートやエラーバウンダリも同じファイル内で管理可能
2. エントリーポイント(index.tsx
)
// 1. importセクション
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
// 2. 関数定義セクション
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
// 3.4 返り値構築・ロジックセクション
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
export {};
-
ReactDOM.createRoot
でルートコンテナを生成 -
<App />
に全ルーター構造を統合 -
StrictMode
により副作用チェックや将来互換性を向上
2. ルーター統合コンポーネント(App.tsx
)
// 1. importセクション
import React from 'react';
import { createBrowserRouter, RouterProvider, Outlet, useRouteError, isRouteErrorResponse } from 'react-router-dom';
import { HomeScreen } from './pages/HomeScreen/HomeScreen';
import { IntroScreen } from './pages/IntroScreen/IntroScreen';
import { FeatureA } from './pages/FeatureA/FeatureA';
import { FeatureB } from './pages/FeatureB/FeatureB';
import { NotFound } from './pages/NotFound/NotFound';
// 2. 関数定義セクション
// 未実装ページ用プレースホルダー
const ComingSoon: React.FC = () => <div>Coming Soon...</div>;
// エラーバウンダリ
const RootErrorBoundary: React.FC = () => {
const error = useRouteError();
if (isRouteErrorResponse(error)) {
return (
<div>
<h1>{error.status} - {error.statusText}</h1>
{error.data?.message && <p>{error.data.message}</p>}
</div>
);
}
return <div>Something went wrong</div>;
};
// レイアウト
const AppLayout: React.FC = () => (
<div style={{ padding: '20px' }}>
<Outlet />
</div>
);
// ルーター作成
const router = createBrowserRouter([
{
path: '/',
element: <AppLayout />,
errorElement: <RootErrorBoundary />,
children: [
{ index: true, element: <IntroScreen /> },
{ path: 'home', element: <HomeScreen /> },
{ path: 'feature-a', element: <FeatureA /> },
{ path: 'feature-b', element: <FeatureB /> },
{ path: 'feature-c', element: <ComingSoon /> },
{ path: '*', element: <NotFound /> }
]
}
]);
// 3.4 返り値構築・ロジックセクション
function App() {
return <RouterProvider router={router} />;
}
// 4. exportセクション
export default App;
-
createBrowserRouter
でルート定義を直接記述 -
children
配列でネストルーティングを実現 -
errorElement
でルートレベルの例外を統合的に管理 - 未実装ページはプレースホルダーで対応
3. ページコンポーネント例
pages/HomeScreen/HomeScreen.tsx
import React from 'react';
export const HomeScreen: React.FC = () => <h1>Home Page</h1>;
pages/IntroScreen/IntroScreen.tsx
import React from 'react';
export const IntroScreen: React.FC = () => <h1>Welcome to the App</h1>;
pages/NotFound/NotFound.tsx
import React from 'react';
export const NotFound: React.FC = () => <h1>404 - Page Not Found</h1>;
まとめ
- React Router 6 では
createBrowserRouter
とRouterProvider
が中心 -
App.tsx
にルート定義を集約すると、シンプルで理解しやすい構成になる - ネストルートやエラーバウンダリも同一ファイルで管理可能
- 将来的にルート数が増えたら
routes/
に分離することで保守性を高められる