1
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?

[エラー対応] Vitest で useNavigate() may be used only in the context of a <Router> component. が出た時の解決方法

Posted at

はじめに

Vitest でテストを書いたら useNavigate() 関連のエラーに遭遇したので、原因と解決策をまとめます。

発生したエラーメッセージ

テスト実行時に以下のエラーが発生しました。

Error: useNavigate() may be used only in the context of a <Router> component.
 ❯ Login src/pages/Login.tsx:14:22
     12| 
     13| export const Login = () => {
     14|     const navigate = useNavigate();
       |                      ^

エラー発生時のコード

loginTest.spec.tsx
import { render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { Login } from "../pages/Login";

describe("初期表示", () => {
    test("タイトルが表示できること", async () => {
        render(
            <MemoryRouter>
                <Login />
            </MemoryRouter>
        );

        await waitFor(() => {
            const title = screen.getByTestId("testLoginTitle");
            expect(title).toHaveTextContent("ログイン画面");
        });
    });
});
Login.tsx
import { signInWithGoogle } from "../service/auth";
import { useEffect, useState } from "react";
import { supabase } from "../utils/supabase";
//ログイン直後に使用するユーザー情報
import { User as SupabaseUser } from "@supabase/supabase-js";
import { fetchUser } from "../service/fetchUser";
import { useNavigate } from "react-router";
import { Header } from "../components/Header";


export const Login = () => {
    const navigate = useNavigate();
    // 認証ユーザー
    const [authUser, setAuthUser] = useState<SupabaseUser | null>(null); 
    const [bootstrapping, setBootstrapping] = useState(true);

原因

Login.tsx では react-router から useNavigate を import していました。
一方、テストでは react-router-domMemoryRouter を使用していたため、異なる Router コンテキストを参照してしまいエラーが発生していました。

解決策

Login.tsxの import を修正するだけで解決しました。

Login.tsx
import { signInWithGoogle } from "../service/auth";
import { useEffect, useState } from "react";
import { supabase } from "../utils/supabase";
//ログイン直後に使用するユーザー情報
import { User as SupabaseUser } from "@supabase/supabase-js";
import { fetchUser } from "../service/fetchUser";
- import { useNavigate } from "react-router";
+ import { useNavigate } from "react-router-dom";
import { Header } from "../components/Header";

おわりに

エラーログを読んでいても「import が原因」とまでは気づけませんでした。
今回の学びとして、エラーの最初の1行目 と スタックトレースに最初に出てくる自作ファイル を確認すれば、原因に直結することが分かりました。
また、react-router-dom は内部で react-router をラップしているため、Webアプリ開発では基本的に react-router-dom を使うべきだと理解できました。

参考

1
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
1
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?