快速筆記:在 react-router-dom 5 實作條件路由
總結
目前手上有一個專案是使用 react 18 搭配 react-router-dom 5 來進行開發,在實作「條件式路由+懶載入」的途中,持續遇到「進入不存在的路由時,404 畫面消失,畫面只剩一片空白」的情況。此篇筆記將記錄一下最後能順利作用的程式碼為何。
版本與環境
react: 18.2.0
react-router-dom: 5.3.4
筆記
需求描述
- 使用 react 的
lazy
搭配Suspense
元件 - 根據
env.isDevelopment
來決定是否要讓使用者進入/something-develop-only
這個畫面,在非開發環境下,試圖進入/something-develop-only
的使用者會被送到/404
頁 - 暫不考慮使用帳號系統來做權限管理
程式碼
重點:
React.Suspense
要包在Switch
外層- 作為
React.Suspense
的 fallback 元件不使用懶載入
import React, { lazy, Suspense } from 'react';
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import Loading from '@Component/Page/Loading';
import env from '@Model/env';
const Landing = lazy(() => import('@Component/Page/Landing'));
const SomePage = lazy(() => import('@Component/Page/SomePage'));
const DevelopmentOnly = lazy(() => import('@Component/Page/DevelopmentOnly'));
const NotFound = lazy(() => import('@Component/Page/NotFound'));
function Router(): React.ReactElement {
return (
<BrowserRouter>
<Suspense fallback={<Loading />}>
<Switch>
<Route path="/" exact>
<Landing />
</Route>
<Route path="/page1">
<SomePage />
</Route>
<Route path="/development-only" exact>
{env.isDevelopment ? <DevelopmentOnly /> : <Redirect to="/404" />}
</Route>
<Route path="/404">
<NotFound />
</Route>
<Route path="*">
<Redirect to="/404" />
</Route>
</Switch>
</Suspense>
</BrowserRouter>
);
}
export default Router;
備註:以下兩種寫法可以互換,效果相同
寫法ㄧ:根據 env.isDevelopment
與否決定顯示 DevelopmentOnly
或 Redirect
元件
<Route path="/develop-only" exact>
{env.isDevelopment ? <DevelopmentOnly /> : <Redirect to="/404" />}
</Route>
寫法二:根據 env.isDevelopment
來決定是否要在 Switch
元件內顯示 /develop-only
這條路由的 Route
元件
{
env.isDevelopment && (
<Route path="/develop-only" exact>
<DevelopmentOnly />
</Route>
);
}