Skip to content

React Router V6 で useRoutes() が Router コンテキスト外で使用されるエラーの解決方法

問題の説明

React Router V6 で useRoutes() フックを使用する際に、以下のエラーが発生することがあります:

Error: useRoutes() may be used only in the context of a <Router> component.

このエラーは、React Router の機能(useRoutesRoutesRoute など)が適切な Router コンテキスト外で使用されている場合に発生します。

原因

React Router V6 では、すべてのルーティング機能が Router コンテキストを必要とします。このコンテキストは BrowserRouterHashRouterMemoryRouter などの Router コンポーネントによって提供されます。

主な原因は以下の通りです:

  1. Router コンポーネントでアプリケーションがラップされていない
  2. 異なるバージョンの react-router-dom が混在している
  3. 誤ったインポート(react-router と react-router-dom の混同)

解決方法

方法 1: アプリケーションを BrowserRouter でラップする

最も一般的な解決策は、アプリケーション全体を BrowserRouter コンポーネントでラップすることです。

index.js (推奨)

js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

TIP

アプリケーションのエントリーポイント(index.js)で Router を設定するのがベストプラクティスです。これにより、アプリ全体でルーティング機能が利用可能になります。

方法 2: App.js 内で Router を設定する

エントリーポイントを変更できない場合は、App.js 内で対応することも可能です。

App.js

js
import { BrowserRouter, useRoutes } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
// 他のページインポート

const AppRoutes = () => {
  const routes = useRoutes([
    { path: '/', element: <Home /> },
    { path: 'o-nama', element: <About /> },
    // 他のルート定義
  ]);
  return routes;
};

const App = () => {
  return (
    <BrowserRouter>
      <AppRoutes />
    </BrowserRouter>
  );
};

export default App;

方法 3: インポートの確認

誤ったモジュールからのインポートがないか確認してください。

間違ったインポート(動作しない)

js
import { Routes, Route } from 'react-router';  // 誤り

正しいインポート

js
import { Routes, Route } from 'react-router-dom';  // 正しい

WARNING

react-routerreact-router-dom は別パッケージです。Web アプリケーションでは必ず react-router-dom からインポートしてください。

方法 4: パッケージのバージョン確認

複数のバージョンの react-router-dom がインストールされていないか確認してください。

bash
npm list react-router-dom
# または
yarn list react-router-dom

複数のバージョンが検出された場合は、全てのパッケージをアンインストール後、最新バージョンを再インストールします。

bash
npm uninstall react-router-dom
npm install react-router-dom@latest

完全な実装例

以下に、React Router V6 を正しく使用する完全な実装例を示します。

index.js

js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

App.js

js
import { useRoutes } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Services from './pages/Services';
import Gallery from './pages/Gallery';
import Prices from './pages/Prices';
import Contact from './pages/Contact';

const App = () => {
  const routes = useRoutes([
    { path: '/', element: <Home /> },
    { path: 'o-nama', element: <About /> },
    { path: 'usluge', element: <Services /> },
    { path: 'galerija', element: <Gallery /> },
    { path: 'cjenovnik', element: <Prices /> },
    { path: 'kontakt', element: <Contact /> }
  ]);

  return routes;
};

export default App;

INFO

React 18 では ReactDOM.render の代わりに ReactDOM.createRoot を使用します。古いバージョンの React を使用している場合は適宜読み替えてください。

まとめ

useRoutes() may be used only in the context of a <Router> component エラーは、React Router の機能が適切なコンテキスト外で使用されている場合に発生します。この問題を解決するには:

  1. アプリケーションを BrowserRouter でラップする
  2. 正しいパッケージからインポートしているか確認する(react-router-dom
  3. パッケージのバージョン競合がないか確認する

これらの対策により、React Router V6 の機能を正しく利用できるようになります。