react-router-dom v6 知識(shí)整合
?一、路由模塊的安裝?
npm install react-router-dom
// 目前版本: v6.3
官方案例:
二、路由各組件?
1. BrowserRouter / HashRouter 相當(dāng)于容器(類似router-view),用于指定路由的模式
BrowserRouter為history模式
HashRouter為hash模式
注意:BrowserRouter組件最好放在最頂層所有組件之外,這樣能確保內(nèi)部組件使用Link做路由跳轉(zhuǎn)時(shí)不出錯(cuò)
如下:
2. Route 定義具體的路由
<Route path="/expenses" element={<Home/>} />
path 為路由名 , element 為對(duì)應(yīng)的組件
注:element 的值 必須 寫成標(biāo)簽的形式
3. 老版本V5 中的作用路由
示例:
如上代碼:
在當(dāng)用戶輸入/product時(shí),將會(huì)匹配到兩個(gè)路由,/ 及 /product ;則會(huì)顯示兩個(gè)組件 ;
原因是老版本路由在匹配時(shí),是進(jìn)行模糊匹配
解決方案:
步驟1:使用Switch讓路由只能匹配一個(gè); 注意順序問題,路由先從上向下進(jìn)行匹配
步驟2:使用exact關(guān)鍵字,讓路由進(jìn)行精準(zhǔn)匹配
?<Route path="/" exact component={Home} />
加上以上關(guān)鍵字,路由將會(huì)精準(zhǔn)匹配,只會(huì)匹配,path為”/" 的路由
4. V6中的 組件Routes
v6 中 Switch 名稱變?yōu)?Routes , 且Route 標(biāo)簽必須包含在Routes標(biāo)簽里,會(huì)不然報(bào)錯(cuò)
也就是說,路由只能匹配到一個(gè),不會(huì)在出現(xiàn)多個(gè)路由匹配的情況
5. v6 中,exact 屬性不再需要
v6 內(nèi)部算法改變,不再需要加exact實(shí)現(xiàn)精確匹配路由,默認(rèn)就是匹配完整路徑。
如果需要舊的行為(模糊匹配),路徑后加/*
<Route path="/products/*" element={<Products />} />
<Route path="/products/:productId" element={<ProductDetail />} />
測(cè)試: /prodcuts 顯示
/products/4 顯示
/products/haha 顯示
/products/haha/hehe 顯示
結(jié)論:看第6點(diǎn):React Router 能夠自動(dòng)找出最優(yōu)匹配路徑 ,順序不重要
若:path屬性取值為*時(shí),可以匹配任何(非空)路徑,同時(shí)該匹配擁有最低的優(yōu)先級(jí)??梢杂糜谠O(shè)置404頁面。
6. v6 中,Route 先后順序不再重要,React Router 能夠自動(dòng)找出最優(yōu)匹配路徑
7. v6 保留Link,NavLink
Link,NavLink 類似與a標(biāo)準(zhǔn),區(qū)別NavLink可以設(shè)置高亮樣式
<Link to="/home">首頁</Link>
NavLink的使用,及激活狀態(tài)的樣式設(shè)置
V5老版本,activeClassName設(shè)置,或activeStyle
V6新版本,activeClassName 與 activeStyle屬性被移除
可以直接在的className和style中使用一個(gè)函數(shù)來設(shè)置激活狀態(tài)的樣式。
方法:通過箭頭函數(shù)接收到isActive參數(shù)值,通過isActive的值來設(shè)置
通過className
通過style
fontWeight: "bold" 不管是否激活,都會(huì)有; 因?yàn)闆]有判斷
8. Navigate組件
<Route path="/" element ={<Navigate replace to="/home" />} />
<Navigate replace to="" />是對(duì)舊的 Redirect 的完整取代。
replace 屬性也可以省略,不過行為由 replace 改為 push
replace vs push
????????this.props.history.push('router地址')
????????push:?a-b-c,可以回到上一級(jí)
????????push跳轉(zhuǎn)會(huì)形成history,可返回到上一層。
????????this.props.history.replace('router地址')
????????replace:?a-b-c 回不到上一級(jí) 適用于登錄后,不需要重新回到登頁面
????????replace跳轉(zhuǎn)不會(huì)形成history,不可返回到上一層。
????????結(jié)論: push有歷史記錄,replace沒有歷史記錄
9. V6中嵌套路由改為相對(duì)路徑
嵌套路由必須放在 中,且使用相對(duì)路徑,不再像 v5 那樣必須提供完整路徑,因此路徑變短。
上面的訪問路徑為 /about/address , /about/information, /about/joinus
10. 使用Outlet組件
此組件是一個(gè)占位符,告訴 React Router 嵌套的內(nèi)容應(yīng)該放到哪里。
11. 使用index 指定默認(rèn)路由, 或者path為空
<Route path='/about' element={<About />}>
? ? <Route index element={<Address />} />
? ? <Route path='address' element={<Address />}></Route>
? ? <Route path='information' element={<Information />}></Route>
? ? <Route path='joinus' element={<Join />}></Route>
</Route>?
或者
設(shè)置path為空,來指定默認(rèn)路由
12. useRoutes 聲明式的路由配置方式
聲明式路由中,不能寫index, 可以讓path: "" , 來實(shí)現(xiàn)顯示默認(rèn)組件;
useRoutes函數(shù),會(huì)返回已經(jīng)渲染好的路由元素
13. v6 用useNavigate實(shí)現(xiàn)編程式導(dǎo)航,useHistory被移除
如果要重定向:
navigate("/welcome",{replace:true});
除此之外,還可以使用navigate(-1)后退到前一頁,使用navigate(-2)后退到前一頁的前一頁,navigate(1)前向?qū)Ш剑?/p>
注:V5版本中的編程式路由導(dǎo)航?this.props.history.replace() 與 ?this.props.history.push();
在V6中useNavigate 替代
詳細(xì)版本:
// v6版本編程導(dǎo)航使用 useNavigate (以下為引入代碼)
1.push跳轉(zhuǎn)+攜帶params參數(shù)
navigate(`/b/child1/${id}/${title}`);
2.push跳轉(zhuǎn)+攜帶search參數(shù)
navigate(`/b/child2?id=${id}&title=${title}`);
3.push跳轉(zhuǎn)+攜帶state參數(shù)
navigate("/b/child2", { state: { id, title }});
4.replace跳轉(zhuǎn)+攜帶params參數(shù)
navigate(`/b/child1/${id}/${title}`,{replace: true});
5.replace跳轉(zhuǎn)+攜帶search參數(shù)
navigate(`/b/child2?id=${id}&title=${title}`,{replace: true});
6.replace跳轉(zhuǎn)+攜帶state參數(shù)
navigate("/b/child2", { state: { id, title },replace: true});
14. useSearch 獲取路由參數(shù)的方法
在Route組件中的path屬性中定義路徑參數(shù)
在組件內(nèi)通過useParams hook訪問路徑參數(shù)
在以前版本中,組件的props會(huì)包含一個(gè)match對(duì)象,在其中可以取到路徑參數(shù)。但在最新的6.x版本中,無法從props獲取參數(shù)。
并且,針對(duì)類組件的withRouter高階組件已被移除。
因此對(duì)于類組件來說,使用參數(shù)有兩種兼容方法:
1. 將類組件改寫為函數(shù)組件傳遞
2. 寫一個(gè)HOC來包裹類組件,用useParams獲取參數(shù)后通過props傳入原本的類組件
15. useSearchParams 獲取seach 參數(shù)
查詢參數(shù)不需要在路由中定義
使用useSearchParams hook來訪問查詢參數(shù)。其用法和useState類似,會(huì)返回當(dāng)前對(duì)象和更改它的方法
更改searchParams時(shí),必須傳入所有的查詢參數(shù),否則會(huì)覆蓋已有參數(shù)
但在最新的6.x版本中,無法從props獲取參數(shù)。在類組件中獲取seach參數(shù)的值,解決方法與上面一樣.
16. useLocation 獲取傳遞的state值
1.傳遞參數(shù)
或
navigate("/b/child2", { state: { id, title }});
2.接收參數(shù)
注: prop屬性中的location已經(jīng)沒有了,所以在類組件不能獲取到相應(yīng)的數(shù)據(jù)了,
解決方案就是1. 寫成函數(shù) 2. 使用高階組件HOC (13,14,15,16 都是這樣)
17. 多組路由
通常,一個(gè)應(yīng)用中只有一個(gè)Routes組件。
但根據(jù)實(shí)際需要也可以定義多個(gè)路由出口(如側(cè)邊欄和主頁面都要隨URL而變化)
18. 路由組件懶加載
安裝: npm i?@loadable/component
import loadable from '@loadable/component'
?const ComponentNode = loadable(()=>{
? ? ? ? ? ? return import("./"+item.componentPath)
? ? ? ? })
<Route path={item.path} element={<ComponentNode />}>
19. 動(dòng)態(tài)路由案例
菜單數(shù)據(jù):
動(dòng)態(tài)路由生成組件:
更多內(nèi)容,請(qǐng)關(guān)注公主號(hào):bug收集