【React Router 教學】#01 什麼是前端路由?React Router 快速入門

測驗:React Router 快速入門

共 5 題,點選答案後會立即顯示結果

1. 什麼是 SPA(單頁應用程式)的核心特性?

  • A. 每次點擊連結都會向伺服器請求新的 HTML 頁面
  • B. 整個網站只有一個 HTML 檔,用 JavaScript 切換畫面內容
  • C. 必須使用 React 框架才能建立
  • D. 不支援瀏覽器的上一頁/下一頁功能

2. 在 React Router 中,為什麼應該使用 <Link> 而不是 <a> 標籤來建立導覽連結?

  • A. <Link> 的語法比較簡短
  • B. <a> 標籤在 React 中無法使用
  • C. <Link> 會用 JavaScript 攔截點擊,只更新需要的部分而不重載頁面
  • D. <Link> 可以自動處理 SEO 優化

3. 以下哪個元件必須包住整個 App,才能讓應用程式使用 React Router 的路由功能?

  • A. <BrowserRouter>
  • B. <Routes>
  • C. <Route>
  • D. <Link>

4. 在以下程式碼中,當網址是 /about 時,會顯示什麼?

<Routes> <Route path=”/” element={<Home />} /> <Route path=”/about” element={<About />} /> <Route path=”*” element={<NotFound />} /> </Routes>
  • A. <Home /> 元件
  • B. <About /> 元件
  • C. <NotFound /> 元件
  • D. 三個元件同時顯示

5. 前端路由是透過什麼瀏覽器 API 來改變網址列但不重新載入頁面?

  • A. DOM API
  • B. Fetch API
  • C. Storage API
  • D. History API

一句話說明

前端路由讓單頁應用程式(SPA)可以切換頁面,但不用重新載入整個網頁。


這篇文章會教你什麼

讀完這篇,你會看懂:

  • SPA 和傳統網站的差別
  • 為什麼需要前端路由
  • React Router 的基本設定長什麼樣
  • 當 AI 幫你建立路由時,你知道它在幹嘛

先搞懂:SPA 是什麼?

傳統多頁面網站

用戶點擊連結
    ↓
瀏覽器向伺服器請求新頁面
    ↓
伺服器回傳完整 HTML
    ↓
整個頁面重新載入(白畫面閃一下)

單頁應用程式(SPA)

用戶點擊連結
    ↓
JavaScript 攔截點擊
    ↓
只更新需要變動的部分
    ↓
網址改變,但頁面不重載(超順暢)

一句話:SPA 就是「整個網站只有一個 HTML 檔,用 JavaScript 來切換畫面內容」。


前端路由 vs 後端路由

特性 後端路由 前端路由
處理位置 伺服器 瀏覽器
切換速度 慢(需要網路請求) 快(本地切換)
頁面載入 整頁重載 局部更新
網址變化 真的換頁 假的換頁(History API)

翻譯

  • 後端路由:「你要 /about 頁面?我去伺服器拿一個新的 HTML 給你。」
  • 前端路由:「你要 /about 頁面?我把現在畫面的內容換成 About,順便改一下網址讓你以為換頁了。」

History API:前端路由的魔法

瀏覽器有個內建功能叫 History API,讓 JavaScript 可以:

  1. 改變網址列顯示的網址
  2. 不重新載入頁面

最小範例

// 改變網址列,但不重載頁面
window.history.pushState({}, '', '/about');

// 現在網址列顯示 /about,但頁面還是原來的
Code language: JavaScript (javascript)

這在幹嘛pushState/about 加入瀏覽歷史,網址列也會顯示 /about,但不會真的去請求新頁面。

React Router 就是把這個 API 包裝起來,讓我們用更簡單的方式處理路由。


React Router v6 安裝

安裝套件

npm install react-router-dom

一句話react-router-dom 是給網頁用的,還有一個 react-router-native 是給手機 App 用的。


30 秒範例:第一個路由

目錄結構

src/
├── App.jsx
├── pages/
│   ├── Home.jsx
│   └── About.jsx
└── main.jsx

main.jsx

import { BrowserRouter } from 'react-router-dom';  // 引入路由容器
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
  <BrowserRouter>    {/* 用 BrowserRouter 包住整個 App */}
    <App />
  </BrowserRouter>
);
Code language: JavaScript (javascript)

App.jsx

import { Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';

function App() {
  return (
    <div>
      {/* 導覽列 */}
      <nav>
        <Link to="/">首頁</Link>         {/* Link 不是 <a>,但效果一樣 */}
        <Link to="/about">關於</Link>
      </nav>

      {/* 路由區域:根據網址顯示對應元件 */}
      <Routes>
        <Route path="/" element={<Home />} />        {/* / 顯示 Home */}
        <Route path="/about" element={<About />} />  {/* /about 顯示 About */}
      </Routes>
    </div>
  );
}
Code language: JavaScript (javascript)

Home.jsx

function Home() {
  return <h1>歡迎來到首頁</h1>;
}

export default Home;
Code language: JavaScript (javascript)

About.jsx

function About() {
  return <h1>關於我們</h1>;
}

export default About;
Code language: JavaScript (javascript)

逐行翻譯

import { BrowserRouter } from 'react-router-dom';
// 引入 BrowserRouter,這是使用 History API 的路由容器
Code language: JavaScript (javascript)
<BrowserRouter>
  <App />
</BrowserRouter>
// 用 BrowserRouter 包住 App,讓裡面的元件可以使用路由功能
Code language: HTML, XML (xml)
import { Routes, Route, Link } from 'react-router-dom';
// Routes:放所有路由規則的容器
// Route:單一條路由規則
// Link:點擊後切換路由的連結(不會重載頁面)
Code language: JavaScript (javascript)
<Link to="/">首頁</Link>
// 像 <a href="/">,但點擊時不會重載頁面
// 改用 JavaScript 切換路由
Code language: HTML, XML (xml)
<Routes>
  <Route path="/" element={<Home />} />
</Routes>
// 當網址是 / 時,在這個位置顯示 <Home /> 元件
Code language: PHP (php)

核心概念翻譯表

你會看到 意思
<BrowserRouter> 路由功能的開關,包住整個 App
<Routes> 放路由規則的容器
<Route path="/" element={<Home />} /> 網址是 / 時顯示 Home
<Link to="/about"> 點擊後跳到 /about(不重載頁面)
path 要匹配的網址路徑
element 匹配成功時要顯示的元件

AI 最常這樣用

用法 1:基本頁面路由

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/products" element={<Products />} />
  <Route path="/contact" element={<Contact />} />
</Routes>
Code language: PHP (php)

翻譯:定義三個頁面,根據網址顯示對應內容。

用法 2:有導覽列的版面

function App() {
  return (
    <>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>

      <main>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </main>

      <footer>Copyright 2024</footer>
    </>
  );
}
Code language: JavaScript (javascript)

翻譯:導覽列和頁尾固定不動,只有 <Routes> 裡面的內容會隨網址改變。

用法 3:找不到頁面(404)

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="*" element={<NotFound />} />   {/* 其他都顯示 404 */}
</Routes>
Code language: PHP (php)

翻譯path="*" 是萬用字元,匹配所有其他網址。


必看懂 vs 知道就好

必看懂(這篇會用到)

  • <BrowserRouter> – 路由容器
  • <Routes><Route> – 定義路由規則
  • <Link> – 不重載頁面的連結
  • pathelement – 網址對應元件

知道就好(後面的文章會教)

  • 巢狀路由(<Outlet>
  • 動態路由(/users/:id
  • 程式化導航(useNavigate
  • 路由參數(useParams

Vibe Coder 檢查點

看到 AI 寫的路由代碼時確認:

  • [ ] 有沒有用 <BrowserRouter> 包住整個 App?
  • [ ] <Routes> 裡面是不是只有 <Route>
  • [ ] 連結是用 <Link> 還是 <a>?(應該用 <Link>
  • [ ] 有沒有處理 404?(path="*"
  • [ ] 路由的 pathelement 對應正確嗎?

常見問題

Q:為什麼用 <Link> 不用 <a>

// 錯誤:會重載整個頁面
<a href="/about">關於</a>

// 正確:只更新路由,不重載
<Link to="/about">關於</Link>
Code language: HTML, XML (xml)

<a> 會觸發瀏覽器的預設行為(重載頁面),<Link> 會用 JavaScript 攔截點擊,只更新需要的部分。

Q:BrowserRouter 和 HashRouter 差在哪?

BrowserRouter HashRouter
網址長相 /about /#/about
需要伺服器設定 需要 不需要
比較常用 舊專案可能會看到

一句話:新專案用 BrowserRouter 就對了。


小結

這篇學到了:

  1. SPA:一個 HTML,JavaScript 切換內容
  2. 前端路由:改網址但不重載頁面
  3. React Router 三元素
    • BrowserRouter – 路由容器
    • Routes + Route – 路由規則
    • Link – 導航連結

下一篇會教「巢狀路由」,學會怎麼讓多個頁面共用同一個版面配置。


延伸:知道就好

這些進階功能遇到再查:

  • HashRouter:用 # 符號的路由,不需要伺服器設定
  • MemoryRouter:路由狀態存在記憶體,網址列不會變(測試用)
  • StaticRouter:伺服器端渲染用的路由
  • unstable_HistoryRouter:自訂 history 物件

進階測驗:React Router 快速入門

測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。

1. 你正在建立一個電商網站,需要有首頁、商品列表、購物車三個頁面。你希望導覽列和頁尾固定不動,只有中間內容區塊會隨網址改變。應該如何設計? 情境題

  • A. 在每個頁面元件中都重複寫導覽列和頁尾的程式碼
  • B. 把導覽列和頁尾放在 <Routes> 外面,讓 <Routes> 只包含會變動的內容
  • C. 使用三個不同的 <BrowserRouter> 來分別管理三個區塊
  • D. 把所有內容都放在 <Routes> 裡面,讓每個 <Route> 包含完整頁面

2. 小明的同事寫了以下程式碼,但點擊「關於我們」連結時,整個頁面會閃一下白畫面然後重新載入。問題出在哪裡? 錯誤診斷

<nav> <a href=”/”>首頁</a> <a href=”/about”>關於我們</a> </nav> <Routes> <Route path=”/” element={<Home />} /> <Route path=”/about” element={<About />} /> </Routes>
  • A. <Routes> 應該放在 <nav> 裡面
  • B. 缺少 path="*" 的 404 處理
  • C. 應該使用 <Link to="..."> 而不是 <a href="...">
  • D. <Route>element 屬性寫法錯誤

3. 你要建立一個部落格網站,當使用者輸入不存在的網址(如 /xyz123)時,應該顯示「找不到頁面」的提示。應該如何實作? 情境題

  • A. 在 <BrowserRouter> 上加入 onNotFound 屬性
  • B. 使用 try-catch 包住 <Routes>
  • C. 在每個 <Route> 加入 fallback 屬性
  • D. 新增一個 <Route path="*" element={<NotFound />} />

4. 小華的 React 應用程式在開發時運作正常,但部署到伺服器後,直接輸入網址 https://example.com/products 會出現 404 錯誤。最可能的原因是什麼? 錯誤診斷

  • A. React Router 版本太舊
  • B. 伺服器沒有設定將所有路徑導向 index.html(BrowserRouter 需要伺服器支援)
  • C. 缺少 <BrowserRouter> 元件
  • D. /products 路由沒有正確定義

5. 你要在 main.jsx 中設定 React Router。以下哪個寫法是正確的? 情境題

// 選項 A ReactDOM.createRoot(document.getElementById(‘root’)).render( <App> <BrowserRouter /> </App> ); // 選項 B ReactDOM.createRoot(document.getElementById(‘root’)).render( <BrowserRouter> <App /> </BrowserRouter> ); // 選項 C ReactDOM.createRoot(document.getElementById(‘root’)).render( <Routes> <App /> </Routes> ); // 選項 D ReactDOM.createRoot(document.getElementById(‘root’)).render( <Route> <App /> </Route> );
  • A. 選項 A
  • B. 選項 B
  • C. 選項 C
  • D. 選項 D

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *