React Routerは、Reactアプリケーションでナビゲーションを管理し、シームレスなルーティング機能を提供するために使用される人気のルーティングライブラリです。しかし、どのライブラリでもそうですが、徐々に更新や変更が行われ、一部の機能が非推奨、サポート外となるため、エラーになることがあります。

Reactアプリケーションでルーティングを実装する際に発生しがちなエラーに「’Switch’ is not exported from ‘react-router-dom’」というものがあります。

このエラーは、React Routerの古いバージョンから新しいバージョン(現在はv6)にアップグレードする際に、<Switch>のようないくつかの非推奨のコンポーネントを考慮しないと発生する恐れがあります。

そこで今回は、Reactアプリケーションのスムーズなルーティングとナビゲーションを確保するために、このエラーの原因と解決方法をご紹介します。

「’Switch’ is not exported from ‘react-router-dom’」エラーの原因とは

React Routerバージョン5以前では、Reactアプリケーションのルートをラップするのに<Switch>コンポーネントが使用されていました。React Routerバージョン6では、<Switch>コンポーネントは非推奨となり、<Routes>コンポーネントに置き換えられています。

React Router v6の<Routes>コンポーネントは、非推奨の<Switch>コンポーネントと比較して、より宣言的で柔軟なルーティングを可能にします。

結果として、React Router v6(またはより新しいバージョン)に切り替え、非推奨の<Switch>コンポーネントを使用したままだと、「’Switch’ is not exported from ‘react-router-dom’ 」というエラーが発生することになります。

「'Switch' is not exported from 'react-router-dom' 」というエラー
「’Switch’ is not exported from ‘react-router-dom’ 」というエラー

「’Switch’ is not exported from ‘react-router-dom’」エラーの2つの対処方法

このエラーは、プロジェクトの要件に応じて、2つの方法で対処することができます。その2つの方法とは、以下の通りです。

  • <Switch>の代わりに<Routes>を使用する
  • react-router-domのバージョンを5以下にダウングレードする

1. <Switch>の代わりに<Routes>を使用する

「’Switch’ is not exported from ‘react-router-dom’」エラーを解決する一つの方法が、<Switch><Routes>に置き換えることです。

例として、React Routerバージョン5で非推奨の<Switch>コンポーネントを使用しているコードを、React Routerバージョン6の新しい<Routes>コンポーネントに更新する方法を見てみましょう。

React Routerバージョン5では以下の通りです。

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';

const App = () => {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Switch>
    </Router>
  );
};

export default App;

上記のコードでは、<Switch>コンポーネントを使用してルートをラップしています。しかし、React Routerバージョン6では、<Routes>コンポーネントを使用し、最新のAPIに従う必要があります。

以下、同じ例をバージョン6以降のReact Routerのものに書き換えてみます。

import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';

const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </Router>
  );
};

export default App;

ご覧のように、<Switch>コンポーネントを<Routes>コンポーネントに置き換え、各<Route>componentの代わりにelementを使用して定義されています。

React Router v6におけるSwitchを超えるRoutesの優位性

React Router v6のリリースでは、<Routes>コンポーネントの導入により、以前のバージョンの(現在は非推奨である)<Switch>コンポーネントに比べていくつもの改善点がもたらされました。

続いては、Reactアプリケーションでルーティングロジックを処理するのに<Routes>を使用する利点を簡単に見てみましょう。

1. ネストされたルーティングの改善

<Routes>では<Switch>に比べて、ネストされたルーティングをより優れた方法で扱うことができます。<Routes>では、<Route>コンポーネントを他の<Route>コンポーネントにネストさせることで簡単にルートを定義し、複雑なルーティング構造をより直感的かつ整理して設計できるようになりました。

これにより、複数のレベルのネストされたルートを持つ大規模なアプリケーションにおいて、ルーティングロジックの管理を簡素化することができます。

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />}>
    <Route path="/team" element={<Team />} />
    <Route path="/history" element={<History />} />
  </Route>
  <Route path="/contact" element={<Contact />} />
</Routes>
2. ダイナミックルートマッチング

<Routes>は、ルートパラメータに基づいて動的にルートをマッチングし、レンダリングすることで、より柔軟な対応を可能にします。これにより、アプリケーションでより動的かつデータ駆動型のルーティングを行うことができます。

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/users/:userId" element={<UserProfile />} />
  <Route path="/products/:productId" element={<ProductDetail />} />
</Routes>
3. エラー処理の改善

<Routes>では、一致しないルートに対するエラー処理も改善されています。ルートが見つからない場合、<Routes>は自動的に「Not Found」コンポーネント(または定義したカスタムエラーコンポーネント)をレンダリングします。

これにより、無効なURLやアプリケーションに存在しないルートを臨機応援に処理し、ユーザーエクスペリエンスを向上させることができます。

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  {/* Error route */}
  <Route path="*" element={<NotFound />} />
</Routes>

2. react-router-domのバージョンを5以下に下げる

プロジェクトで<Switch>の使用を継続したい場合には、react-router-domのバージョンを5以下にダウングレードし、エラーを解決することもできます。

これは、すでに古いバージョンのReact Routerを使用してプロジェクトを構築している場合には、有効な解決策となる可能性があります。まず以下のコマンドを使用してReact routerの最新バージョンをアンインストールします。

npm uninstall react-router-dom

続いて、以下のコマンドを使用して、<Switch>コンポーネントを含む最後のメジャーリリースであるバージョン5.2.0をインストールします。

npm install [email protected]

まとめ

この記事では、Reactのエラー「’Switch’ is not exported from ‘react-router-dom’ 」について学び、それを解決するいくつかの方法を探りました。また、非推奨の<Switch>コンポーネントではなく、新しい<Routes>コンポーネントを使用するメリットもご紹介しました。

プロジェクトを新たに立ち上げる際には、常に最新バージョンのReact Routerを使用することをお勧めします。実際に大幅な改善と継続的なアップデートが実現しています。

とは言え、既存のプロジェクトに取り組んでいて、React Router v6の構文とコンポーネントにあわせてコードを広範囲に調整する時間がないのであれば、旧バージョンのReact Routerに切り替えましょう。

あなたは、この問題に直面したことがありますか?どのように解決したでしょうか。また、この記事で取り上げていない他のアプローチをご存知でしょうか?コメント欄でお聞かせください。