Skip to content

Router v6 で 'Switch' がインポートできない問題と解決策

問題概要

React Router v6 を使用している際に、'Switch' is not exported from 'react-router-dom' というエラーが発生する場合があります。これは React Router のバージョンアップに伴う破壊的変更によるもので、バージョン 6 では Switch コンポーネントが廃止され、代わりに Routes コンポーネントが導入されたためです。

ソリューション

この問題には主に2つの解決方法があります:

方法1: React Router v6 の新しい構文を使用する(推奨)

最新のバージョンである React Router v6 を使用する場合は、Switch の代わりに Routes を使用します。また、ルートの定義方法も変更されています。

jsx
import {
  BrowserRouter,
  Routes, // Switch の代わり
  Route,
  Link
} from "react-router-dom";

function App() {
  return (
    <div className="App">
      <div>
        <Link to="/">Home</Link>
      </div>
      
      <hr />
      
      <Routes>
        <Route path="/" element={<Home />} />
        {/* 他のルートも同様に定義 */}
      </Routes>
    </div>
  );
}

重要な変更点

  • SwitchRoutes に変更
  • コンポーネントは element プロパティで指定
  • 子要素として直接コンポーネントを記述するスタイルから変更

方法2: React Router v5 にダウングレードする

既存のコードベースを大きく変更したくない場合や、v6 への移行が難しい場合は、v5 を使用し続ける選択肢もあります。

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

v5 から v6 への主な変更点

以下は両バージョンのコード比較です:

jsx
import { HashRouter as Router, Route, Switch } from "react-router-dom";

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/teams/:teamName/matches/:year">
          <MatchPage />
        </Route>
        <Route path="/teams/:teamName">
          <TeamPage />
        </Route>
        <Route path="/">
          <HomePage />
        </Route>
      </Switch>
    </Router>
  );
}
jsx
import { HashRouter as Router, Route, Routes } from "react-router-dom";

function App() {
  return (
    <Router>
      <Routes>
        <Route 
          path="/teams/:teamName/matches/:year" 
          element={<MatchPage/>} 
        />
        <Route 
          path="/teams/:teamName" 
          element={<TeamPage/>} 
        />
        <Route 
          path="/" 
          element={<HomePage/>} 
        />
      </Routes>
    </Router>
  );
}

よくある間違いと解決策

注意点

v6 では各 Route を個別の Routes でラップする必要はありません。以下のようなコードは非効率です:

jsx
// 非推奨: 冗長な書き方
<Routes>
  <Route path="/" element={<Navbar />} />
</Routes>
<Routes>
  <Route path="/" element={<Header />} />
</Routes>

代わりに単一の Routes 内に全ての Route をまとめましょう:

jsx
// 推奨: 効率的な書き方
<Routes>
  <Route path="/" element={<>
    <Navbar />
    <Header />
    <About />
    <Contact />
  </>} />
  <Route path="/signup" element={<Signup />} />
</Routes>

まとめ

React Router v6 では Switch コンポーネントが廃止され、Routes コンポーネントに置き換えられました。新規プロジェクトでは最新の v6 を使用し、新しい構文に慣れることをおすすめします。既存の大規模なプロジェクトでは、移行コストを考慮して v5 を継続使用する選択肢もあります。

詳細については公式の移行ガイドを参照してください。