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會拆解出homeab,然後按順序配對 - 如果第一個沒配對上,後面就不會接續配對
- 需注意是按照順序配對,
嚴格配對
- 當要使用嚴格配對時,在
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
- 例如這時再按