快速筆記:在 react-router-dom 5 實作條件路由

總結

目前手上有一個專案是使用 react 18 搭配 react-router-dom 5 來進行開發,在實作「條件式路由+懶載入」的途中,持續遇到「進入不存在的路由時,404 畫面消失,畫面只剩一片空白」的情況。此篇筆記將記錄一下最後能順利作用的程式碼為何。

版本與環境

react: 18.2.0
react-router-dom: 5.3.4

筆記

需求描述

程式碼

重點:

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 與否決定顯示 DevelopmentOnlyRedirect 元件

<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>
  );
}

參考文件