網(wǎng)站首頁 編程語言 正文
一、基本使用
首先安裝依賴:
npm i react-router-dom
引入實(shí)現(xiàn)路由所需的組件,以及頁面組件:
import { BrowserRouter, Routes, Route } from "react-router-dom"; import Foo from "./Foo"; import Bar from "./Bar"; function App() { return ( <BrowserRouter> <Routes> <Route path="/foo" element={<Foo />} /> <Route path="/bar" element={<Bar />} /> </Routes> </BrowserRouter> ); }
-
path
:路徑 -
element
:要渲染的組件
注意:
BrowserRouter
組件最好放在最頂層所有組件之外,這樣能確保內(nèi)部組件使用 Link 做路由跳轉(zhuǎn)時(shí)不出錯(cuò)
二、路由跳轉(zhuǎn)
在跳轉(zhuǎn)路由時(shí),如果路徑是/
開頭的則是絕對(duì)路由,否則為相對(duì)路由,即相對(duì)于當(dāng)前 URL進(jìn)行改變
2.1 Link 組件
Link組件
只能在Router
內(nèi)部使用,因此使用到Link組件
的組件一定要放在頂層的 Router 之內(nèi)
import { Link } from "react-router-dom"; <Link to="foo">to foo</Link>;
2.2 NavLink 組件
-
NavLink組件
和Link組件
的功能是一致的,區(qū)別在于可以判斷其to屬性
是否是當(dāng)前匹配到的路由 -
NavLink組件
的style
或className
可以接收一個(gè)函數(shù),函數(shù)接收一個(gè)含有isActive
字段的對(duì)象為參數(shù),可根據(jù)該參數(shù)調(diào)整樣式
import { NavLink } from "react-router-dom"; function Foo() { return ( <NavLink style={({ isActive }) => ({ color: isActive ? "red" : "#fff" })}> Click here </NavLink> ); }
2.3 編程式跳轉(zhuǎn)
使用useNavigate
鉤子函數(shù)生成navigate函數(shù)
,可以通過 JS 代碼完成路由跳轉(zhuǎn)
useNavigate
取代了原先版本中的useHistory
import { useNavigate } from 'react-router-dom'; function Foo(){ const navigate = useNavigate(); return ( // 上一個(gè)路徑:/a; 當(dāng)前路徑: /a/a1 <div onClick={() => navigate('/b')}>跳轉(zhuǎn)到/b</div> <div onClick={() => navigate('a11')}>跳轉(zhuǎn)到/a/a1/a11</div> <div onClick={() => navigate('../a2')}>跳轉(zhuǎn)到/a/a2</div> <div onClick={() => navigate(-1)}>跳轉(zhuǎn)到/a</div> ) }
- 可以直接傳入要跳轉(zhuǎn)的目標(biāo)路由(可以使用相對(duì)路徑,語法和 JS 相同)
- 傳入
-1
表示后退
三、動(dòng)態(tài)路由參數(shù)
3.1 路徑參數(shù)
- 在
Route組件
中的path屬性
中定義路徑參數(shù) - 在組件內(nèi)通過
useParams
?hook 訪問路徑參數(shù)
<BrowserRouter> <Routes> <Route path="/foo/:id" element={<Foo />} /> </Routes> </BrowserRouter>; import { useParams } from "react-router-dom"; export default function Foo() { const params = useParams(); return ( <div> <h1>{params.id}</h1> </div> ); }
路徑匹配規(guī)則
當(dāng)URL同時(shí)匹配到含有路徑參數(shù)的路徑和無參數(shù)路徑時(shí),有限匹配沒有參數(shù)的”具體的“(specific)路徑。
<Route path="teams/:teamId" element={<Team />} /> <Route path="teams/new" element={<NewTeamForm />} />
如上的兩個(gè)路徑,將會(huì)匹配?teams/new
?。
路徑的正則匹配已被移除。
兼容類組件
在以前版本中,組件的props
會(huì)包含一個(gè)match對(duì)象
,在其中可以取到路徑參數(shù)。
但在最新的 6.x 版本中,無法從 props 獲取參數(shù)。
并且,針對(duì)類組件的?withRouter
?高階組件已被移除。因此對(duì)于類組件來說,使用參數(shù)有兩種兼容方法:
- 將類組件改寫為函數(shù)組件
- 自己寫一個(gè) HOC 來包裹類組件,用?
useParams
?獲取參數(shù)后通過 props 傳入原本的類組件
3.2 search 參數(shù)
- 查詢參數(shù)不需要在路由中定義
- 使用?
useSearchParams
?hook 來訪問和修改查詢參數(shù)。其用法和?useState
?類似,會(huì)返回當(dāng)前對(duì)象和更改它的方法 - 使用?
setSearchParams
?時(shí),必須傳入所有的查詢參數(shù),否則會(huì)覆蓋已有參數(shù)
import { useSearchParams } from "react-router-dom"; // 當(dāng)前路徑為 /foo?id=12 function Foo() { const [searchParams, setSearchParams] = useSearchParams(); console.log(searchParams.get("id")); // 12 setSearchParams({ name: "foo", }); // /foo?name=foo return <div>foo</div>; }
四、嵌套路由
5.1 路由定義
通過嵌套的書寫Route組件
實(shí)現(xiàn)對(duì)嵌套路由的定義。
path
?開頭為?/
?的為絕對(duì)路徑,反之為相對(duì)路徑。
<Routes> <Route path="/" element={<Home />}></Route> <Route path="/father" element={<Father />}> <Route path="child" element={<Child />}></Route> <Route path=":name" element={<Another />}></Route> </Route> </Routes>
5.2 在父組件中展示
在父組件中使用Outlet
來顯示匹配到的子組件
import { Outlet } from "react-router-dom"; function Father() { return ( <div> // ... 自己組件的內(nèi)容 // 留給子組件Child的出口 <Outlet /> </div> ); }
5.3 在組件中定義
可以在任何組件中使用?Routes
?組件,且組件內(nèi)的Routes中,路徑默認(rèn)帶上當(dāng)前組件的路徑作為前綴。
注意:此時(shí)定義父組件的路由時(shí),要在后面加上?/*
?,否則父組件將無法渲染。
<Routes> <Route path="/" element={<Home />} /> <Route path="dashboard/*" element={<Dashboard />} /> </Routes> function Dashboard() { return ( <div> <p>Look, more routes!</p> <Routes> <Route path="/" element={<DashboardGraphs />} /> <Route path="invoices" element={<InvoiceList />} /> </Routes> </div> ); }
五、默認(rèn)路由
定義:?在嵌套路由中,如果 URL 僅匹配了父級(jí) URL,則Outlet
中會(huì)顯示帶有index
屬性的子路由。可以使用在路由的任何層級(jí)
<Routes> <Route path="/foo" element={Foo}> <Route index element={Default}></Route> <Route path="bar" element={Bar}></Route> </Route> </Routes>
- 當(dāng) url 為
/foo
時(shí):Foo 中的 Outlet 會(huì)顯示 Default 組件 - 當(dāng) url 為
/foo/bar
時(shí):Foo 中的 Outlet 會(huì)顯示為 Bar 組件
六、全匹配路由
定義:??path
屬性取值為*
時(shí),可以匹配任何(非空)路徑,該匹配擁有最低的優(yōu)先級(jí)。可以用于設(shè)置 404 頁面。
<Routes> <Route path="/foo" element={Foo}> <Route path="bar" element={Bar}></Route> <Route path="*" element={NotFound}></Route> </Route> </Routes>
七、多組路由
通常,一個(gè)應(yīng)用中只有一個(gè)Routes
組件。
但根據(jù)實(shí)際需要也可以定義多個(gè)路由出口(如:側(cè)邊欄和主頁面都要隨 URL 而變化)
<Router> <SideBar> <Routes> <Route></Route> </Routes> </SideBar> <Main> <Routes> <Route></Route> </Routes> </Main> </Router>
八、路由重定向
當(dāng)在某個(gè)路徑/a
下,要重定向到路徑/b
時(shí),可以通過Navigate
組件進(jìn)行重定向到其他路徑
等價(jià)于以前版本中的
Redirect
組件
import { Navigate } from "react-router-dom"; function A() { return <Navigate to="/b" />; }
九、布局路由
當(dāng)多個(gè)路由有共同的父級(jí)組件時(shí),可以將父組件提取為一個(gè)沒有?path
?和?index
?屬性的Route組件(Layout Route)
<Route element={<PageLayout />}> <Route path="/privacy" element={<Privacy />} /> <Route path="/tos" element={<Tos />} /> </Route>
這種寫法等價(jià)于:
<Route path="/privacy" element={ <PageLayout> <Privacy /> </PageLayout> } /> <Route path="/tos" element={ <PageLayout> <Tos /> </PageLayout> } />
十、訂閱和操作 history stack的原理
瀏覽器會(huì)記錄導(dǎo)航堆棧,以實(shí)現(xiàn)瀏覽器中的前進(jìn)后退功能。在傳統(tǒng)的前端項(xiàng)目中,URL的改變意味著向服務(wù)器重新請(qǐng)求數(shù)據(jù)。
在現(xiàn)在的客戶端路由( client side routing )中,可以做到編程控制URL改變后的反應(yīng)。如在點(diǎn)擊a標(biāo)簽的回調(diào)函數(shù)中使用?event.preventDefault()
?阻止默認(rèn)事件,此時(shí)URL的改變不會(huì)帶來任何UI上的更新。
<a href="/contact" onClick={(event) => { // stop the browser from changing the URL and requesting the new document event.preventDefault(); // push an entry into the browser history stack and change the URL window.history.pushState({}, undefined, "/contact"); }} />
10.1 History對(duì)象
瀏覽器沒有直接提供監(jiān)聽URL改變(push、pop、replace)的接口,因此?react-router
?對(duì)原生的?history
?對(duì)線進(jìn)行了包裝,提供了監(jiān)聽URL改變的API。
let history = createBrowserHistory(); history.listen(({ location, action }) => { // this is called whenever new locations come in // the action is POP, PUSH, or REPLACE });
使用?react-router
?時(shí)不需操作History對(duì)象(Routes
?組件會(huì)進(jìn)行操作)
11.2 Location對(duì)象
react-router
?對(duì)?window.location
?進(jìn)行包裝后,提供了一個(gè)形式簡潔的Location對(duì)象,形如:
{ pathname: "/bbq/pig-pickins", // 主機(jī)名之后的URL地址 search: "?campaign=instagram", // 查詢參數(shù) hash: "#menu", // 哈希值,用于確定頁面滾動(dòng)的具體位置 state: null, // 對(duì)于 window.history.state 的包裝 key: "aefz24ie" // }
state
不顯示在頁面上,不會(huì)引起刷新,只由開發(fā)人員操作。
可用于記錄用戶的跳轉(zhuǎn)詳情(從哪跳到當(dāng)前頁面)或在跳轉(zhuǎn)時(shí)攜帶信息。
可以用在?Link
?組件或?navigate
?方法中
<Link to="/pins/123" state={{ fromDashboard: true }} /> let navigate = useNavigate(); navigate("/users/123", { state: partialUser }); 復(fù)制代碼
在目標(biāo)的組件中,可以用?useLocation
?方法獲取該對(duì)象
let location = useLocation(); console.log(location.state);
state中的信息會(huì)進(jìn)行序列化,因此如日期對(duì)象等信息會(huì)變?yōu)閟tring
key
每個(gè)Location對(duì)象擁有一個(gè)唯一的key,可以據(jù)此來實(shí)現(xiàn)基于Location的滾動(dòng)管理,或是數(shù)據(jù)緩存。
如:將?location.key
?和 URL 作為鍵,每次請(qǐng)求數(shù)據(jù)前,先查找緩存是否存在來判斷是否實(shí)際發(fā)送請(qǐng)求,來實(shí)現(xiàn)客戶端數(shù)據(jù)緩存。
十一、 各類Router組件
11.1 HashRouter和BrowserRouter的區(qū)別
-
HashRouter
?只會(huì)修改URL中的哈希值部分;而?BrowserRouter
?修改的是URL本身 -
HashRouter
?是純前端路由,可以通過輸入U(xiǎn)RL直接訪問;使用時(shí)?BrowserRouter
?直接輸入U(xiǎn)RL會(huì)顯示404,除非配置Nginx將請(qǐng)求指向?qū)?yīng)的HTML文件。初次進(jìn)入?/
?路徑時(shí)或點(diǎn)擊?Link
?組件跳轉(zhuǎn)時(shí)不會(huì)發(fā)送請(qǐng)求
11.2 unstable_HistoryRouter
使用?unstable_HistoryRouter
?需要傳入一個(gè)?history
?庫的實(shí)例,這將允許在非react作用于下操作history對(duì)象。
由于項(xiàng)目使用的history和react-router中使用的history版本可能不一樣,該API目前標(biāo)為unstable狀態(tài)
11.3 MemoryRouter
HashRouter
?和?BrowserRouter
?都是依據(jù)外部對(duì)象(history)進(jìn)行導(dǎo)航,而?MemoryRouter
?則是自己存儲(chǔ)和管理狀態(tài)堆棧,多用于測試場景。
11.4 NativeRouter
推薦的用于 React Native的Router組件
11.5 StaticRouter
在nodejs端使用,渲染react應(yīng)用。
import * as React from "react"; import * as ReactDOMServer from "react-dom/server"; import { StaticRouter } from "react-router-dom/server"; import http from "http"; function requestHandler(req, res) { let html = ReactDOMServer.renderToString( <StaticRouter location={req.url}> {/* The rest of your app goes here */} </StaticRouter> ); res.write(html); res.end(); } http.createServer(requestHandler).listen(3000);
十二、使用JS對(duì)象定義路由:useRoutes
使用?useRoutes
?hook,可以使用一個(gè)JS對(duì)象而不是Routes組件與Route組件來定義路由。其功能類似于react-router-config
useRoutes
?的返回是 React Element,或是 null。
對(duì)于傳入的配置對(duì)象, 其類型定義如下:
interface RouteObject { caseSensitive?: boolean; children?: RouteObject[]; element?: React.ReactNode; index?: boolean; path?: string; }
原文鏈接:https://juejin.cn/post/7142141069096910855
相關(guān)推薦
- 2022-05-12 python遍歷文件夾內(nèi)文件并檢索文件中的中文內(nèi)容
- 2023-07-24 純前端包含,不包含,非,模糊查詢,與,或,
- 2022-04-15 C語言的位段與枚舉詳解_C 語言
- 2022-03-15 box-shadow上下左右四個(gè)邊框設(shè)置陰影樣式
- 2022-04-17 Python?同級(jí)目錄(兄弟目錄)調(diào)用方式_python
- 2022-12-15 Native?Memory?Tracking追蹤區(qū)域示例分析_React
- 2022-03-27 Android關(guān)于BottomNavigationView使用指南_Android
- 2022-10-18 pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別_p
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支