iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Modern Web

前端開發之那些我會的與我不會的技術系列 第 27

React Router Dom:輕鬆掌握前端路由

  • 分享至 

  • xImage
  •  

今天要來介紹的是react-router-dom這個套件,它用來模擬換頁的一套路由工具,讓我們可以使用它來完成Single Page Application(SPA)中變換路徑達成切換頁面的功能。

安裝

npm install react-router-dom

使用

  • createBrowserRouter

使用createBrowserRouter建立路由的規範。path為路徑element為在這個路徑的時候要呈現的內容,也可以是React元件

import {
  createBrowserRouter
} from "react-router-dom";

const router = createBrowserRouter([
  {
		// 在根目錄呈現的是<div>Hello world!</div>
    path: "/", 
    element: <div>Hello world!</div>, 
  },
  {
		// 在/deom路徑呈現的是<div>demo</div>
    path: "/demo",
    element: <div>demo</div>,
  },
]);

在root的地方包一層<RouterProvider>並帶入*createBrowserRouter建立的路由規範,被包住的<App />底下都可以操作路徑等的路由功能。

import {
  RouterProvider 
} from "react-router-dom";

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router}>      
      <App />
    </RouterProvider>
  </React.StrictMode>,
)
  • <BrowserRouter>

也可以使用<BrowserRouter>來建立路由規則,使用<BrowserRouter />包著<Routes>再包著帶入path和element的<Route>

import React from 'react'
import ReactDOM from 'react-dom/client'
import {
  BrowserRouter,
  Route,
  Routes
} from "react-router-dom";

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <BrowserRouter basename="/">
      <Routes>
        <Route path="/" element={<App />} />
        <Route path="/demo" element={<Demo />} />
        <Route path="/artical/:articalID" element={<Artical />} />
      </Routes>
    </BrowserRouter>
  </React.StrictMode>,
)

兩種用法大同小異就看習慣哪種

變更路由

在元件裡也可以使用<Link>這個react-router-dom提供的元件來切換路徑

import { Link } from "react-router-dom";
export default function App() {
  return <Link to={`/demo`}>DEMO PAGE</Link>
}

在程式理切換路徑

使用useNavigate回傳的function,帶入路徑可以用程式的方式切換路徑

import { Link, useNavigate } from "react-router-dom";

export default function Demo() {
  const navigate = useNavigate();
  return <button onClick={() => {
        navigate("/");
      }}>TO Home PAge </button>
}

直接return<Navigate />

當元件return<Navigate />,會在渲染到這裡時導頁至參數to的路徑

import { Navigate } from "react-router-dom";

function App() {
	return	<Navigate to="/" />;
}

路由參數

在path參數的路徑使用分號+變數名稱,就可以使用動態路由,路徑會是/artical/任意值,例如/artical/abc

{
    path: '/artical/:articalID',
    element: <Artical />
}

使用useParams抓取動態路由的值,如果路徑為/artical/abc,下面範例的articalID就會是abc

import { useParams } from 'react-router-dom';
export default function Artical() {
  const { articalID } = useParams();
  return <div>{articalID}</div>
}

巢狀路由

我們可以在路由裡設定,根據路徑讓父層的元件裡面插入另一塊元件
https://ithelp.ithome.com.tw/upload/images/20231012/20162751b6lVb6Iy3D.png

  • 使用createBrowserRouter建立

在path為/demo的物件新增一個children參數,裡面放入要呈現的內容

import {
  createBrowserRouter,
  Outlet,
} from "react-router-dom";
const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: "/demo",
    element: <Demo />,
    children: [
      {
        path: "id",
        element: <div>demo children</div>,
      },
    ],

  },
]);

<Demo />元件裡面放入<Outlet />,在config children裡的element將會呈現在<Outlet />的位置

import {
  Outlet,
} from "react-router-dom";
export default function Demo() {
  const navigate = useNavigate();
  return <>
		<div> demo page </div>
		<Outlet />
  </>
}
  • 使用<*BrowserRouter>建立*

在demo的<Route>底下建立一個children的<Route>

<BrowserRouter basename="/">
  <Routes>
    <Route path="/" element={<App />} />
    <Route path="/demo" element={<Demo />}>
      <Route path="id" element={<div>demo children</div>} />
    </Route>
  </Routes>
</BrowserRouter>

路由守衛Protected Routes

我們在有些頁面會需要登入或是驗證才可以瀏覽頁面,我們可以在路由要瀏覽的元件外包一層元件,這個元件可以用來檢查有沒有登入或是驗證,沒有登入的話就會把使用者導到其他頁面,如果有登入就可以瀏覽底下的children元件。

這邊的範例使用Props來傳入loginStatus,但是也可以用其他方式,像是在元件裡面抓取cookie的資料等方式來判斷有沒有登入。

import { Navigate } from "react-router-dom";
export default function RouterGuard({children, loginStatus}) {
  if (!loginStatus) {
		return <Navigate to="/" replace />; //沒有登入就會導到首頁
  }
	return children
}

路由設定

<Private />的父層包裹<RouterGuard >

<BrowserRouter basename="/">
  <Routes>
    <Route path="/" element={<App />} />
    <Route path='/private' element={
      <RouterGuard loginStatus={true}>
        <Private />
      </RouterGuard>
    } />
  </Routes>
</BrowserRouter>

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: 'private',
    element: <RouterGuard loginStatus={true}>
      <Private />
    </RouterGuard>
  },

參考

https://reactrouter.com/en/main
https://www.robinwieruch.de/react-router-private-routes/


上一篇
React中使用CSS的三種方式:CSS Modules、styled-components和Tailwind
下一篇
網站埋碼、Google Tag Manager以及dataLayer的指南
系列文
前端開發之那些我會的與我不會的技術31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言