如何修復React中的 “‘Switch’ is not exported from ‘react-router-dom'” 錯誤

attempted-import-error-featured-1024x512-1

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 及更早版本中,<Switch> 元件用於封裝 React 應用程式中的所有路由。在 React Router 版本 6 中,<Switch> 元件已被棄用,取而代之的是 <Routes> 元件。

與已廢棄的 <Switch> 元件相比,React Router v6 中的 <Routes> 元件提供了一種宣告性更強、更靈活的路由方法。

因此,如果您最近升級到了 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 種方法

根據專案的預期方法和要求,有兩種方法可以解決這一錯誤。這兩種方法如下:

  • 使用 <Routes> 而不是 <Switch>
  • 將 react-router-dom 版本降級到 5 或以下

1. 使用 <Routes> 而不是 <Switch>

修復 “‘Switch’ is not exported from ‘react-router-dom'” 錯誤的一種方法是將 <Switch> 替換為 <Routes>

讓我們來看一個示例,看看如何將路由程式碼從 React Router 版本 5 中已廢棄的 <Switch> 元件更新為 React Router 版本 6 中的新 <Routes> 元件。

在 React Router 版本 5 中:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
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;
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

下面是相同示例在 React Router 版本 6 及以後的版本中的效果:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
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;
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;

正如你所看到的,我們用 <Routes> 元件替換了 <Switch> 元件,現在每個 <Route> 都是使用 element 道具而不是 component 道具定義的。

提示:在 React Router 第 6 版中不再需要精確的道具,因為它是預設行為。此外,<Route> 元件不再使用 component={Home} 來分配元件,而是使用 element={<Contact/>}

React Router v6 中路由比交換機的優勢

隨著 React Router v6 的釋出,<Routes> 元件的引入與之前版本中已廢棄的 <Switch> 元件相比帶來了一些優勢。

讓我們來看看在 React 應用程式中使用 <Routes> 處理路由邏輯的一些優勢。

1. 改進巢狀路由

<Switch> 相比, <Routes> 允許改進巢狀路由配置。使用 <ROutes>,您可以通過在其他 <Route> 元件中巢狀 <Route> 元件來輕鬆定義巢狀路由,從而更直觀、更有條理地處理複雜的路由結構。

這有助於簡化具有多層巢狀路由的大型應用程式中的路由邏輯管理。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<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>
<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>
<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> 在根據路由引數動態匹配和呈現路由方面提供了更大的靈活性。這樣就能在應用程式中實現更加動態和資料驅動的路由選擇。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:userId" element={<UserProfile />} />
<Route path="/products/:productId" element={<ProductDetail />} />
</Routes>
<Routes> <Route path="/" element={<Home />} /> <Route path="/users/:userId" element={<UserProfile />} /> <Route path="/products/:productId" element={<ProductDetail />} /> </Routes>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:userId" element={<UserProfile />} />
<Route path="/products/:productId" element={<ProductDetail />} />
</Routes>

3. 改進的錯誤處理

This can help improve the user experience by gracefully handling invalid URLs or routes that do not exist in your application.

<Routes> 為未匹配的路由提供了改進的錯誤處理。如果未找到路由, <Routes> 會自動顯示 “Not Found” 元件或您可以定義的自定義錯誤元件。

這樣就可以優雅地處理應用程式中不存在的無效 URL 或路由,從而幫助改善使用者體驗。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
{/* Error route */}
<Route path="*" element={<NotFound />} />
</Routes>
<Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> {/* Error route */} <Route path="*" element={<NotFound />} /> </Routes>
<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 路由器:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm uninstall react-router-dom
npm uninstall react-router-dom
npm uninstall react-router-dom

現在,您可以使用該命令安裝包含 <Switch> 元件的最後一個主要版本,即 5.2.0 版:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install react-router-dom@5.2.0
npm install react-router-dom@5.2.0
npm install react-router-dom@5.2.0

小結

在本文中,您瞭解了 React 中的錯誤 “‘Switch’ is not exported from ‘react-router-dom'”,並探索了幾種修復方法。您還了解了使用較新的 <Routes> 元件而非過時的  <Switch> 元件的優勢。

在開始一個新專案時,建議始終使用最新版本的 React Router,因為它提供了顯著的改進和持續的更新。

但是,假設您正在開發一個現有專案,而且沒有時間大量更新程式碼以使用新的 React Router v6 語法和元件。在這種情況下,請繼續使用與您的程式碼相容的舊版 React Router。

現在輪到你了: 您遇到過這個問題嗎?你是如何解決的?您還使用過本文未涉及的其他方法嗎?請在評論中告訴我們!

評論留言