React 基本的路由結構

繼 Vue 以後的第二個前端路由。

簡述

先來看一下結構長怎樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Router 有分成 HashRouter / BrowserRouter
// 這個留到下面再做說明
import { HashRouter as Router, Routes, Route, Link } from "react-router-dom";
<Router>
<Link to="/">home</Link>
<Link to="/about">about</Link>
<Link to="/categories">categories</Link>
<Link to="/posts">posts</Link>
<Link to="/log-in">log in</Link>
<Link to="//sign-up">/sign up</Link>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/categories" element={<CategoriesPage />} />
<Route path="/posts" element={<PostsPage />} />
<Route path="/posts/:id" element={<SinglePostPage />} />
<Route path="/log-in" element={<LoginPage />} />
<Route path="/sign-up" element={<SignUpPage />} />
</Routes>
</Router>
  • <Router> 這邊是用來管理路由的元件,請務必把所有內容都放在這裡面。
  • <Link> 其實就是 <a>,用來設定點下時該跳轉到哪個頁面
  • <Routes> 用來匹配路由的元件,在 V6 之前叫做 <Switch>
  • <Route path="..." element="..."> 用來設定不同路由要顯示哪個 Component。

基本結構大致就是這樣!接下來會講一些補充內容。

Router 的種類,HashRouter 與 BrowserRouter

Router 其實有兩種選擇:

1
2
3
4
// 有 hash
import { HashRouter as Router } from "react-router-dom"
// 沒有 hash(用 History API 實現)
import { BrowserRouter as Router } from "react-router-dom"

這兩個差在如果是 hash mode 的話,對 server 而言你都是在請求同一個檔案,因此不會 404。

1
2
3
不管是哪一個,你永遠都是在對 example.com 發出 request
https://example.com/#/home
https://example.com/#/about

但如果是 History API,server 就會認為你是在找不同的檔案,所以找不到對應資源時就會回傳 404。

1
2
3
瀏覽器分辨不出來,所以會直接發出 request
https://example.com/home
https://example.com/about

總而言之,如果希望網址不要出現 #,就得到 server 設定一些東西,讓每個路由都一律導向 index.html,這樣就不會出現 404 的問題了。但如果你很懶得調的話就用 hash mode 吧!

動態路由

有些時候路由是動態產生的,像 /posts/1 posts/2 這種後面的數字不是固定的,就會用到。

設定方式也很簡單,就跟 Express 的寫法差不多:

1
2
3
4
5
6
7
<Router>
<NavBar />
<Routes>
{/* 希望接收的參數 */}
<Route path="/posts/:id" element={<SinglePostPage />} />
</Routes>
</Router>

接著在 <SinglePostPage /> 就可以透過 useParams 來取得參數值:

1
2
3
4
5
export default function SinglePostPage() {
// 解構拿出來
const { id } = useParams();
console.log('id:', id);
}
使用 useState 要注意初始值的設定 使用 useContext 要注意的細節
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×