コンテンツにスキップ

react routerでRouteを切る

最終更新日: 2021-04-02
  • react-router で Route を切る実装例

確認環境

Env Ver
React 17.0.1
react-router-dom 5.2.0
TypeScript 4.1.3

サンプルコード

index.tsx

  • ここに大元のルーティングを実装
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import React from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
import { BrowserRouter } from 'react-router-dom';
import { RootRoute } from './routes/RootRoute';

// ドメインルート以外にReactを設置する場合に必要
// e.g. `https://www.example.com/react/` に設置する場合 `/react` を設定
const basename = process.env.REACT_APP_BASE_NAME ?? undefined;

ReactDOM.render(
    <React.StrictMode>
        {/* `useHistory()` 用のDIラッパー */}
        <BrowserRouter basename={basename}>
            {/* ルーティング設定をまとめたコンポーネント */}
            <RootRoute />
        </BrowserRouter>
    </React.StrictMode>,
    document.getElementById('root')
);

AppRoute.ts

  • ルーティングの定義、これがあると後々の管理が楽
    • スプレッド演算子で Route に対して展開できるように記述しておく
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
export const AppRoute = {
    // React のルート定義
    root: {
        path: '/',
        key: '/',
        exact: true, // 完全一致
        component: App,
    },
    // 404 定義
    notfound: {
        component: NotFound,
    },
    // `/foo` 以下のルーティング定義
    foo: {
        // `/foo` のルート定義
        root: {
            path: '/foo',
            key: '/foo',
            component: FooRoute,
        },
        // 以下、 `/foo` 配下のページのルーティング定義
        hoge: {
            path: '/foo/hoge',
            key: '/foo/hoge',
            component: HogePage,
        },
        piyo: {
            path: '/foo/piyo',
            key: '/foo/piyo',
            component: PiyoPage,
        },
    },
};

RootRoute.tsx

  • 各階層の基底ルーティング管理
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
export const RootRoute = () => {
  return (
    {/* `Route` は `Switch` で囲む */}
    <Switch>
      {/* root */}
      <Route {...AppRoute.root} />

      {/* foo */}
      <Route {...AppRoute.foo.root} />

      {/* bar */}
      <Route {...AppRoute.bar.root} />

      {/* 404 */}
      <Route {...AppRoute.notfound} />
    </Switch>
  );
};

FooRoute.tsx

  • /foo 階層配下の管理用
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
export const FooRoute = () => {
  return (
    {/*
      `Context` は `Switch` の外に出す
      `Switch` の中に `Context` を書くと更に `Switch` でネストする必要がある
    */}
    <FooContext.Provider value={FooContextDefault}>
      <Switch>
        {/* eslint-disable-next-line array-callback-return */}
        {Object.entries(AppRoute.foo).map(([idx, route]) => {
          if (idx !== 'root') {
            /* `'root'` 以外の全ノードを展開 */
            return <Route {...route} />;
          }
        })}
        {/* 404 */}
        <Route {...AppRoute.notfound} />
      </Switch>
    </FooContext.Provider>
  );
};