總結
目前手上有一個專案是使用 react 18 搭配 react-router-dom 5 來進行開發,在實作「條件式路由+懶載入」的途中,持續遇到「進入不存在的路由時,404 畫面消失,畫面只剩一片空白」的情況。此篇筆記將記錄一下最後能順利作用的程式碼為何。
版本與環境
react: 18.2.0react-router-dom: 5.3.4筆記
需求描述
- 使用 react 的
lazy搭配Suspense元件 - 根據
env.isDevelopment來決定是否要讓使用者進入/something-develop-only這個畫面,在非開發環境下,試圖進入/something-develop-only的使用者會被送到/404頁 - 暫不考慮使用帳號系統來做權限管理
程式碼
重點:
React.Suspense要包在Switch外層- 作為
React.Suspense的 fallback 元件不使用懶載入
import Loading from "@Component/Page/Loading";import env from "@Model/env";import React, { lazy, Suspense } from "react";import { BrowserRouter, Redirect, Route, Switch } from "react-router-dom";
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> );}