React - Route 基礎路由
React - Route 基礎路由
為什麼要使用路由?
- 使用路由實作 SPA 網頁,可以減少頻寬浪費,提高使用體驗
什麼是 SPA?
在講 Route 之前,要先介紹一下什麼是 SPA
- SPA 是單頁網路應用,全名是 Single-Page Application
- 整個應用只有一個完整頁面
- 點擊頁面中的導航連結不會刷新整個頁面,只會頁面局部刷新
- 資料都透過 AJAX 請求獲取,並在前端異步展現
什麼是 Route 路由?
- 路由就是網站的中間站 ( key: value )
- key 為路徑path,value 可能是後端的function或前端的component
如何使用路由?
安裝 React-Router-DOM 套件
- 終端機輸入
npm i react-router-dom
引用並使用 React-Router-DOM 套件
導覽連結(導航區) - 編寫路由連結
在需使用導覽連結的檔案上面引入
1
import { NavLink } from 'react-router-dom';
導覽連結的
<a href='./your_path'>
標籤
換成<NavLink to='/your_path'>
- 需注意大小寫,
href
換成to
,且路徑前面不要加.
- 需注意大小寫,
引入路由組件(展示) - 註冊路由
在需使用引入路由組件的檔案上面引入
1
import { Route } from 'react-router-dom';
引入路由組件原本的
<Your_component />
標籤
換成<Route path="/your_path" component={Your_component}/>
- 需注意大小寫
渲染畫面
在共同渲染畫面的檔案上面引入
1
import { BrowserRouter } from 'react-router-dom';
或
1
import { HashRouter } from 'react-router-dom';
渲染畫面原本的
<App />
標籤
要被<BrowserRouter>
標籤包住,表示同一個路由
(此範例為引入BrowserRouter
)1
2
3<BrowserRouter>
<App />
</BrowserRouter>- 需注意大小寫
BrowserRouter 與 HashRouter 有什麼不同?
- 底層原理不一樣
- BrowserRouter 使用的是 HTML5 的 history API,不兼容 IE9 及以下的版本
- HashRouter url 的哈希值
- path 表現形式不一樣
- BrowserRouter 的路徑中沒有
#
,例如:localhost:3000/demo
- HashRouter 的路徑包含
#
,例如:localhost:3000/#/demo
- BrowserRouter 的路徑中沒有
- 刷新後,對路由 state 參數的影響
- BrowserRouter 沒有任何影響,因為 state 保存在 history 物件中
- HashRouter 刷新後會導致,路由 state 參數的丟失
- 備註 HashRouter 可以解決一些路徑錯誤相關的問題
- BrowserRouter 比較常用
路由組件與一般組件有什麼不同?
一般組件
- 通常放在 components 資料夾
- 直接使用標籤
<Your_component />
- 接收父組件的props
路由組件
- 通常放在 pages 資料夾
- 使用路由標籤
<Route path="/your_path" component={Your_component}/>
- 接收路由器傳遞的固定三個屬性(下面為比較常用的)
- history
- go: ƒ go(n) 📝 前進 n 頁 API, n 可以正或負整數
- goBack: ƒ goBack() 📝 瀏覽器上一頁 API
- goForward: ƒ goForward() 📝 瀏覽器下一頁 API
- push: ƒ push(path, state) 📝 路由跳轉留下紀錄 API
- replace: ƒ replace(path, state) 📝 路由跳轉不留下紀錄 API
- location
- pathname: “/your_path” 📝 獲取當前路徑
- search: “” 📝 傳遞 search 參數用
- state: undefined 📝 傳遞 state 參數用
- match
- params: {} 📝 傳遞 params 參數用
- path: “/your_path” 📝 獲取當前路徑
- url: “/your_path” 📝 獲取當前路徑
- history
與路由相關的問題與功能
NavLink 與 封裝 NavLink
- NavLink 能夠實現路由連結的 active 效果,可以透過
activeClassName
指定樣式名稱 - 標籤體內容是一個特殊的標籤屬性
- 透過
this.props.children
可以獲取標籤體內容
Switch
一般情況如果沒有使用<Switch>
,程式會一路把<Route>
符合路徑的都渲染出來。
使用<Switch>
產生斷點,程式尋找<Route>
一旦找到與<NavLink>
相同路徑,就會終止繼續尋找後面的<Route>
。
進而提升程式運行效率
如何使用 Switch
在要使用 Switch 的檔案引入
import { Switch } from 'react-router-dom'
把
<Route>
用<Switch>
包起來1
2
3
4<Switch>
<Route path="/hello" component={Hello}/>
<Route path="/other" component={Other}/>
</Switch>
樣式丟失問題?
為什麼會丟失
當url
路徑為多層路徑時,例如:http://localhost:3000/mao/about
這時按重新整理(F5),會因為當前路徑的關係,就有可能會丟失樣式。
有 3 個解決辦法
index.html
引入的 CSS 使用絕對路徑,把./
改成/
,
例如:<link rel="stylesheet" href="/your_css.css" />
index.html
引入的 CSS./
改成%PUBLIC_URL%/
,
例如:<link rel="stylesheet" href="%PUBLIC_URL%/your_css.css" />
- 原本引入
<BrowserRouter>
的檔案改使用<HashRouter>
Redirect
當路由都沒辦法配對時,跳轉到 Redirect 所指定的路由
要使用的檔案引入
import { Route, Switch, Redirect } from 'react-router-dom'
把
<Redirect>
放在<Route>
最下面,</Switch>
上面1
2
3
4
5<Switch>
<Route path="/hello" component={Hello}/>
<Route path="/other" component={Other}/>
<Redirect to="/hello" />
</Switch>
嵌套路由
路由裡面還能在套路由,這時路由又叫嵌套路由或多級路由
實作方法與普通路由一樣,只有兩點要注意
路由的配對是按照註冊路由的順序進行配對。
註冊子路由時,要寫上父路由的
path
值。1
2// 父路由 path="/home"
// 子路由 path="/home/about"
路由的模糊配對與嚴格配對
模糊配對
路由默認的情況是模糊配對
- 當
<NavLink to="/home/a/b">
能配對上<Route path="/home">
- 需注意是按照順序配對,
NavLink
會拆解出home
a
b
,然後按順序配對 - 如果第一個沒配對上,後面就不會接續配對
- 需注意是按照順序配對,
嚴格配對
- 當要使用嚴格配對時,在
Route
裡添加exact
,如:<Route exact path="/home">
- 這時要完全一模一樣才能配對
- 注意如果專案沒有因為模糊匹配出現問題,就沒必要使用嚴格配對
路由歷史紀錄的 push 與 replace
歷史紀錄 push
路由默認的情況是push
- 當進行操作時,會留下歷史紀錄痕跡
- 例如這時再按
.../other/message/02
會繼續疊上去 - 按返回則會退回
.../other/message/01
- 例如這時再按
歷史紀錄 replace
- 當要使用 replace 時,在
Route
裡添加replace
,如:如:<Route replace path="/home">
- 這樣進行操作時,不會留下歷史紀錄痕跡
- 例如這時再按
.../other/message/02
會取代.../other/message/01
的紀錄, - 按返回則會退回
.../other/message
- 例如這時再按