🎯

React Routerはルートをどうランク付けしているか

2024/05/13に公開

React Router とは

https://reactrouter.com/en/main

React Router のルートのマッチング

React Router のドキュメントのRanking Routesのセクションを例として説明します。

以下の 5 つのパスパターンを取り得るアプリケーションがあるとして、/teams/newというパスが与えられたときに、どのパスパターンがマッチするでしょうか。

[
  "/",
  "/teams",
  "/teams/:teamId",
  "/teams/:teamId/edit",
  "/teams/new",
];

この場合、/teams/newは以下の 2 つのパスパターンにマッチします。

/teams/:teamId
/teams/new

React Router はここからさらにルートをランク付けし、最終的に/teams/newを最もマッチするルートとして採用します。

どのようにルートをランク付けするか

ランク付けというのは、ルートがどれだけパスにマッチするかを評価することです。React Router は、ルートのパスパターンと与えられたパスを比較し、スコアを計算して最も高いスコアを持つルートを選択します。

スコアの計算処理はcomputeScore関数で行われます。まとめると、以下のようなステップで行われます。

セグメントの分割

  • 説明: パスを"/"で分割してセグメントの配列を作成
  • スコアへの影響: セグメントの数が初期スコア

スプラットチェック

  • 説明: セグメント配列にスプラット("*")が含まれているかを確認
  • スコアへの影響: 含まれていればスコアから 2 点引く(splat penalty)

インデックスルートかのチェック

  • 説明: インデックスルート(通常はデフォルトページ)かどうかを確認
  • スコアへの影響: インデックスであればスコアに 2 点加算

セグメント毎の加算

  • 説明: スプラット以外のセグメントについてループし、スコアを加算
  • スコアへの影響:
    • 静的セグメント: 文字列が定義された静的な値には 10 点を加算
    • 動的セグメント: /:paramNameの形式(例: :userId)には 3 点を加算
    • 空セグメント: パスを "/"で分割(split)した時に生じる空のセグメントには 1 点を加算
      • ex. パスが"/"の場合、① で空セグメントの配列(["", ""])が生成されるので、それがこれに該当する

/teams/:teamId ルートのスコア計算

ステップ 詳細 スコア加算
① セグメントの分割 /, teams, :teamId +3
② スプラットチェック 該当しない -
③ インデックスルートかのチェック 該当しない -
④ セグメント毎の加算
先頭にある/ (空セグメント) +1
teams (静的セグメント) +10
:teamId (動的セグメント) +3
合計スコア 17

/teams/new ルートのスコア計算

ステップ 詳細 スコア加算
① セグメントの分割 /, teams, new +3
② スプラットチェック 該当しない -
③ インデックスルートかのチェック 該当しない -
④ セグメント毎の加算
先頭にある/ (空セグメント) +1
teams (静的セグメント) +10
new (静的セグメント) +10
合計スコア 24

ここから、/teams/newのスコアが/teams/:teamIdのスコアよりも高いため、/teams/newが最もマッチするルートとして採用されます。

ファンタラクティブテックブログ

Discussion