2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【React Router】ルーティング設定を管理しやすくするツールのご紹介

Last updated at Posted at 2021-09-05

【React Router】ルーティング設定を管理しやすくするツールのご紹介

React RouterはReactでルーティングを設定したいときに大変重宝しますが、ページ数の増加やネストが深くなるにつれてコードが読みづらくなり、後からページやネストを追加するのが難しくなる問題があります。

本記事ではこれらの問題を解消するためのツールを作成したので紹介します。
簡単に説明すると設定データからルーティングを生成する仕組みとなっています。

前提

GitHubにデモ用のリポジトリを用意しましたので、これをローカルに入れていることを前提に説明します。

GitHubからダウンロード後、react-router-easy-implementationディレクトリに入り、下記コマンドを実行して必要なモジュールをインストールします。

yarn install

インストールが完了後、下記コマンドでReactの開発環境を起動します。

yarn start

各リンクを押すとページ遷移の動作が確認できます。
(設定されていないパスを入れた場合は「ページが見つかりません」ページに遷移します。)

説明資料1.gif

ディレクトリ構造

./src
├── components
│   └── pages           
│       ├── Page404.tsx # ページデータ
│       ├── Top.tsx     # ページデータ
│       ├── Users.tsx   # ページデータ
│       ├── User1.tsx   # ページデータ
│       ├── User2.tsx#  # ページデータ
│       └── router
│           ├── api                     # ツールのコア
│           ├── routes
│           │   ├── rootRoute.tsx       # localhost:3000/ のルーティング設定データ
│           │   └── usersRoute.tsx      # localhost:3000/users のルーティング設定データ
│           └── types
│               └── RouteType.tsx       # ルーティング設定データの型定義
└── app.tsx # BrowserRouterとPageRouter.tsxをインポート

使い方(ルーティングの設定方法)

/src/components/pages/router/routes/rootRoute.tsxを開くと下記の内容となっています。
このファイルを編集すると、"/"ルートのルーティング設定ができます。

/src/components/pages/router/routes/rootRoute.tsx
// 設定データの型定義
import { RouteType } from "../types/RouteType";

// ページコンポーネント
import { Top } from "../../Top";
import { Page404 } from "../../Page404";

// ネストの設定データ
import { usersRoute } from "./usersRoute";

export const rootRoute: Array<RouteType> = [
  {
    path: "/",
    exact: true,
    children: <Top />
  },
  {
    path: "/users",
    exact: false,
    children: usersRoute
  },
  {
    path: "*",
    exact: false,
    children: <Page404 />
  }
];

ページ設定

rootRoute[0]には下記のオブジェクトが設定されています。

{
  path: "/",
  exact: true,
  children: <Top />
}

childrenにReactNodeが設定されている場合、ページ設定と判断して下記のように変換します。

<Route exact path="/" children={<Top />} />

ネスト設定

一方、rootRoute[1]には下記のオブジェクトが設定されています。

{
  path: "/users",
  exact: false,
  children: usersRoute
},

childrenのusersRouteは同階層のusersRoute.tsxからインポートしたデータです。
このファイルを編集すると、"/users"ルートのルーティングを設定できます。

/src/components/pages/router/routes/usersRoute.tsx(抜粋)
export const usersRoute: Array<RouteType> = [
  {
    path: "/",
    exact: true,
    children: <Users />
  },
  {
    path: "/user1",
    exact: false,
    children: <User1 />
  },
  {
    path: "/user2",
    exact: false,
    children: <User2 />
  },
  {
    path: "*",
    exact: false,
    children: <Page404 />
  }
];

この様な配列データが入っている場合、ネスト設定と判断して最終的に次のように変換します。

<Route
  path="/users"
  render={() => (
    <Switch>
      <Route exact path="/users" children={<Users />} />
      <Route path="/users/user1" children={<User1 />} />
      <Route path="/users/user2" children={<User2 />} />
      <Route path="/users/*" children={<Page404 />} />
    </Switch>
  )}
/>

もし、/user1に対してネストを設定したい場合は、rootRoute.tsxやusersRoute.tsxの同階層に同様のファイルを用意してインポートすると設定できます。
再帰処理でネストを実現しているため、理論上いくらでもネストを設定することができます。

  {
    path: "/user1",
    exact: false,
    children: <User1 />
  }

        ↓

import user1Route from "./user1Route"
//中略
  {
    path: "/user1",
    exact: false,
    children: user1Route
  }

        ↓

<Route path="/users" render={() => (
  <Switch>
    <Route exact path="/users" children={<Users />} />
    <Route path="/users/user1" render={() => (
      <Switch>
        <Route exact path="/users/user1" children={<User1 />} />
        <Route path="/users/user1/hoge" children={<Hoge />} />
        <Route path="/users/user1/*" children={<Page404 />} />
      </Switch>
    )}
    <Route path="/users/user2" children={<User2 />} />
    <Route path="/*" children={<Page404 />} />
  </Switch>
)}/>

おまけ

スニペット

/src/components/pages/router/routes/にルーティングのファイルを作成する際に便利なTypeScriptのスニペットを用意しました。
react-router-pageと入力するとスニペットが展開されます。
("prefix"で呼び出し名の変更が可能)

typescript.json
{
  "React Router Page Setting": {
    "prefix": "react-router-page",
    "body": [
      "// 設定データの型定義",
      "import { RouteType } from '../types/RouteType';",
      "",
      "export const ${TM_FILENAME_BASE}: Array<RouteType> = [",
      "\t{",
      "\t\tpath: '$1',",
      "\t\texact: $2,",
      "\t\tchildren: $3",
      "\t},",
      "];"
    ],
    "description": ""
  }
}

型定義について

設定データを安全に設定できるようにArray<RouteType>で型を定義しています。
RouteTypeの定義は次の通りです。

/src/components/pages/router/types/RouteType.tsx
import { ReactNode } from "react";

export type RouteType = {
  path: string;
  exact: boolean;
  children: ReactNode | Array<RouteType>;
};

## 最後
最後まで読んでいただきありがとうございます。
質問や改善点ございましたら、Qiita記事の返信かGitHubのリポジトリへissueをいただけると幸いです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?