
はじめに
React Router を使ったコンポーネントでよく出るエラーのひとつが、useParams()
で URL パラメータが取得できずにテストが落ちることでした。
ここでは、そのエラーの原因と解決方法を整理します。
useParams()とは
React Router のフックのひとつです。
const { id } = useParams();
このように書くと、/user/abc123
のようなURLから id: "abc123"
を取得できる。
ただしRouterコンテキストの中でしか使えないです。
今回は useParams を使って、URLの id に応じたユーザーの個人ページ(例:/taro → 太郎さんのページ)を表示するために使いました。
エラーの例
TypeError: Cannot read properties of undefined (reading 'id')
このエラーは useParams()
で id
を読み込もうとしているのに、
テスト中は id
を持つ URL パラメータが渡っていない状態で起こりました。
エラーの原因n
const { id } = useParams();
上記のようなコードがあるコンポーネント(例:Card
)を
テストでこう書いて失敗しました。
render(Card />); // ← URL が無い
useParams()
は React Router のコンテキストが無いと動きません。
MemoryRouter で仮URLを与えて解決
テストでは MemoryRouter
を使って、仮の URL を与えます。
MemoryRouterとは
React Router の Router
の一種で、
テスト中に「仮のURL履歴」を作るためのラッパーです
initialEntries
MemoryRouter に渡す initialEntries は、仮のURL履歴を表す配列です。
このように書くと、最初にアクセスしているURLを「/taro」と仮定してくれます。
これにより、useParams() が正しく id: “taro” を返すようになります。
render(
MemoryRouter initialEntries={["/taro"]}>
Routes>
Route path="/:id" element={Card />} />
Routes>
MemoryRouter>
);
これで useParams()
が { id: "taro" }
を返せるようになります。
つまずいたポイント
-
useParams()
はRouterコンテキストの中でしか使えない - 単体で
をrender()
するだけではパラメータが入らない -
MemoryRouter
+initialEntries
を知らないとテストが通らなかった
まとめ
-
useParams()
が必要なコンポーネントはMemoryRouter
で包む -
initialEntries
で仮のURLを渡す -
Route path="/:id"
とelement={}
を組み合わせる
Views: 0