iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Modern Web

React 走出新手村 系列 第 19

React 走出新手村 — 路由基礎

  • 分享至 

  • xImage
  •  

你也是這樣嗎?

有太多新手在基礎還不熟的情況下,只因為路由設定的原因,改學用 Next 框架,但相信我 React-router-dom 真的不難,而且在選擇用不用 Next 的考量不能只是考量 router,更重要的是在架構和渲染機制這篇文章中所提及的概念,那麼這次的分享就是教大家如何整理到能簡單的使用 React-router-dom。

https://ithelp.ithome.com.tw/upload/images/20230918/20129020LpxZpAwKgJ.png

React Router

要學好一樣東西,熟讀官方文件是每個工程師必備的基本義務(官方連結)。當然,我會提供我濃縮完的版本,所以基礎的話可以自行參閱。

  • 步驟 1 — 安裝 react-router-dom

    npm i react-router-dom
    // or
    yarn add react-router-dom
    

    那我這邊目前的版本是 ver. 6.x 的,我不建議拉 ver. 5.x,除非你是維護或是重構舊專案。

  • 步驟 2 — 在 App.tsx 裡面引入 BrowserRouter 將整個 app 的 dom 包住(這裡的例子我是以 vite react 的方式建構專案的),這裡是從我 github 教學檔案拆出來的範例,詳細可以參考連結

    import { FC } from "react"
    import { BrowserRouter, Link, Route, Routes } from "react-router-dom"
    import About from "./pages/About"
    import Contact from "./pages/Contact"
    import Home from "./pages/Home"
    import NotFonud from "./pages/NotFonud"
    import Shirts from "./pages/Shirts"
    import ShirtWid from "./pages/Shirts/ShirtWid"
    import Shop from "./pages/Shop"
    
    // BrowserRouter 就像 redux 的 provider 一樣,必須在最上層來處理
    // Routes 裡面包的事處理所有路由導向的頁面
    // Route 代表的是該路徑下需要渲染的 components
    // 為了方便示範我先生成幾個頁面在 pages 的資料夾內
    const App: FC = () => {
      // navbar可自行腦補方便跳轉頁面的component
      return (
        <BrowserRouter>
          <Navbar/>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="about" element={<About />} />
            <Route path="shop" element={<Shop />} >
              <Route path="shirts">
                {/* nesting 的做法 */}
                <Route index element={<Shirts/>} />
                <Route path=":id" element={<ShirtWid/>} />
              </Route>
            </Route>
            <Route path="contact" element={<Contact />} />
            {/* 對未設定的路由可以採以下方式 */}
            <Route path="*" element={<NotFonud />} />
          </Routes>
        </BrowserRouter>
      )
    }
    
    export default App
    

    上面是基本的應用範例,接下來的步驟是將其濃縮,讓他更為方便管理。

  • 步驟 3 — 在根目錄下新增RouteConf.tsx的檔案,然後將原本在 Routes 裡面的邏輯做更改如下:

    import React from 'react'
    import { useRoutes } from 'react-router-dom'
    import Layout from './components/Layout'
    import About from './pages/About'
    import Contact from './pages/Contact'
    import Home from './pages/Home'
    import Pants from './pages/Pants'
    import PantWid from './pages/Pants/PantWid'
    import Shirts from './pages/Shirts'
    import ShirtWid from './pages/Shirts/ShirtWid'
    import Shop from './pages/Shop'
    
    // 這就是比較推薦的做法,將所有的routes拆出來做統一的管理
    // 包含了每一層的從屬關係,都可以透過下列的表很清處的看到
    // 這裡我們可以嘗試使用react-router-dom 的 <Outlet>,來處理我們常駐在畫面的navbar
    // 我這裡將這些東西拆出來用Layout的component去做封裝,類似像mantine的app shell在處理
    // 當然這裡也可以是需求將element內的component做layz loading的動作來提升FCP效能
    const routes = [
      {
        path: "/",
        element: <Layout />,
        children: [
          { index: true, element: <Home /> },
          { path: "about", element: <About />},
          { 
            path: "shop", 
            element: <Shop />,
            children: [
              { 
                path: "shirts", 
                element: <Shirts/>,
              },
              {
                path: "shirts/:id",
                element: <ShirtWid/>,
              },
              {
                path: "pants",
                element: <Pants />,
              },
              {
                path: "pants/:id",
                element: <PantWid />,
              },
            ]
          },
          {
            path: "contact",
            element: <Contact />,
          }
        ]
      },
    ]
    
    const RouteConf = () => {
      const routeConfig = useRoutes(routes)
      return routeConfig
    }
    
    export default RouteConf
    
  • 步驟 4 — 回到App.tsx做修改如下:

    import { FC } from "react"
    import { BrowserRouter } from "react-router-dom"
    import RouteConf from "./RouteConf"
    
    // 全部交由RouteConf來進行路由管理
    const App: FC = () => {
    
      return (
        <BrowserRouter>
          <RouteConf/>
        </BrowserRouter>
      )
    }
    
    export default App
    

分類結構

之後的資料夾結構可以參考我 github 連結的專案結構,或者你想使用 Next 的 route 結構就隨個人或團隊喜好決定,這裡我沒提及那些 hook 的使用,但我相信大家可以很輕鬆的在官網文件或是我 github 連結的教學,學到基本或更進階的應用。

總結

路由真的沒有那麼複雜,使用 Next 框架的考量觀念也不應該只鎖定在 Router,尤其在新手階段還不清楚 React 的運作機制就跳去使用 Next 的全端框架,只會把簡單的問題複雜化,導致後續學習的頓挫感。

我是自學派的,自學東西的動機,必須建立在學這個東西能解決我現在問題,並且不會產生過多的副作用為主。

不然,等我學會了又多出更多問題,這頭都沒消化完全,那頭開始產生更多問題,只會更加雜亂。

先熟悉 CSR,再慢慢搞懂什麼情況下,需要使用不同渲染模式的作法來達到目的?

這樣的循序漸進你會比較清楚每個框架的思維邏輯。

給全新手的大禮包

React基本Hook教學


上一篇
React 走出新手村 — 在組件裡犯的錯(II)
下一篇
React 走出新手村 — 創造合邏輯的組件
系列文
React 走出新手村 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言