2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

useParams()でidがundefinedになるテストエラーの解決法【React Router】

Posted at

はじめに

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コンテキストの中でしか使えない
  • 単体で <Card />render() するだけではパラメータが入らない
  • MemoryRouter + initialEntries を知らないとテストが通らなかった

まとめ

  • useParams() が必要なコンポーネントは MemoryRouter で包む
  • initialEntries で仮のURLを渡す
  • Route path="/:id"element={<対象コンポーネント />} を組み合わせる
2
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?