react-router-dom?v6?使用詳細(xì)示例
一、基本使用
首先安裝依賴:
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)時不出錯
二、路由跳轉(zhuǎn)
在跳轉(zhuǎn)路由時,如果路徑是/開頭的則是絕對路由,否則為相對路由,即相對于當(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可以接收一個函數(shù),函數(shù)接收一個含有isActive字段的對象為參數(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 (
// 上一個路徑:/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)路由(可以使用相對路徑,語法和 JS 相同)
- 傳入
-1表示后退
三、動態(tài)路由參數(shù)
3.1 路徑參數(shù)
- 在
Route組件中的path屬性中定義路徑參數(shù) - 在組件內(nèi)通過
useParamshook 訪問路徑參數(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ù)的”具體的“(specific)路徑。
<Route path="teams/:teamId" element={<Team />} />
<Route path="teams/new" element={<NewTeamForm />} />如上的兩個路徑,將會匹配 teams/new 。
路徑的正則匹配已被移除。
兼容類組件
在以前版本中,組件的props會包含一個match對象,在其中可以取到路徑參數(shù)。
但在最新的 6.x 版本中,無法從 props 獲取參數(shù)。
并且,針對類組件的 withRouter 高階組件已被移除。因此對于類組件來說,使用參數(shù)有兩種兼容方法:
- 將類組件改寫為函數(shù)組件
- 自己寫一個 HOC 來包裹類組件,用
useParams獲取參數(shù)后通過 props 傳入原本的類組件
3.2 search 參數(shù)
- 查詢參數(shù)不需要在路由中定義
- 使用
useSearchParamshook 來訪問和修改查詢參數(shù)。其用法和useState類似,會返回當(dāng)前對象和更改它的方法 - 使用
setSearchParams時,必須傳入所有的查詢參數(shù),否則會覆蓋已有參數(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)對嵌套路由的定義。
path開頭為/的為絕對路徑,反之為相對路徑。
<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)前組件的路徑作為前綴。
注意:此時定義父組件的路由時,要在后面加上 /* ,否則父組件將無法渲染。
<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 僅匹配了父級 URL,則Outlet中會顯示帶有index屬性的子路由??梢允褂迷诼酚傻娜魏螌蛹?/p>
<Routes>
<Route path="/foo" element={Foo}>
<Route index element={Default}></Route>
<Route path="bar" element={Bar}></Route>
</Route>
</Routes>- 當(dāng) url 為
/foo時:Foo 中的 Outlet 會顯示 Default 組件 - 當(dāng) url 為
/foo/bar時:Foo 中的 Outlet 會顯示為 Bar 組件
六、全匹配路由
定義: path屬性取值為*時,可以匹配任何(非空)路徑,該匹配擁有最低的優(yōu)先級??梢杂糜谠O(shè)置 404 頁面。
<Routes>
<Route path="/foo" element={Foo}>
<Route path="bar" element={Bar}></Route>
<Route path="*" element={NotFound}></Route>
</Route>
</Routes>七、多組路由
通常,一個應(yīng)用中只有一個Routes組件。
但根據(jù)實(shí)際需要也可以定義多個路由出口(如:側(cè)邊欄和主頁面都要隨 URL 而變化)
<Router>
<SideBar>
<Routes>
<Route></Route>
</Routes>
</SideBar>
<Main>
<Routes>
<Route></Route>
</Routes>
</Main>
</Router>八、路由重定向
當(dāng)在某個路徑/a下,要重定向到路徑/b時,可以通過Navigate組件進(jìn)行重定向到其他路徑
等價于以前版本中的
Redirect組件
import { Navigate } from "react-router-dom";
function A() {
return <Navigate to="/b" />;
}九、布局路由
當(dāng)多個路由有共同的父級組件時,可以將父組件提取為一個沒有 path 和 index 屬性的Route組件(Layout Route)
<Route element={<PageLayout />}>
<Route path="/privacy" element={<Privacy />} />
<Route path="/tos" element={<Tos />} />
</Route>這種寫法等價于:
<Route
path="/privacy"
element={
<PageLayout>
<Privacy />
</PageLayout>
}
/>
<Route
path="/tos"
element={
<PageLayout>
<Tos />
</PageLayout>
}
/>十、訂閱和操作 history stack的原理
瀏覽器會記錄導(dǎo)航堆棧,以實(shí)現(xiàn)瀏覽器中的前進(jìn)后退功能。在傳統(tǒng)的前端項(xiàng)目中,URL的改變意味著向服務(wù)器重新請求數(shù)據(jù)。
在現(xiàn)在的客戶端路由( client side routing )中,可以做到編程控制URL改變后的反應(yīng)。如在點(diǎn)擊a標(biāo)簽的回調(diào)函數(shù)中使用 event.preventDefault() 阻止默認(rèn)事件,此時URL的改變不會帶來任何UI上的更新。
<a
href="/contact" rel="external nofollow"
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對象
瀏覽器沒有直接提供監(jiān)聽URL改變(push、pop、replace)的接口,因此 react-router 對原生的 history 對線進(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 時不需操作History對象(Routes 組件會進(jìn)行操作)
11.2 Location對象
react-router 對 window.location 進(jìn)行包裝后,提供了一個形式簡潔的Location對象,形如:
{
pathname: "/bbq/pig-pickins", // 主機(jī)名之后的URL地址
search: "?campaign=instagram", // 查詢參數(shù)
hash: "#menu", // 哈希值,用于確定頁面滾動的具體位置
state: null, // 對于 window.history.state 的包裝
key: "aefz24ie" //
}state
不顯示在頁面上,不會引起刷新,只由開發(fā)人員操作。
可用于記錄用戶的跳轉(zhuǎn)詳情(從哪跳到當(dāng)前頁面)或在跳轉(zhuǎn)時攜帶信息。
可以用在 Link 組件或 navigate 方法中
<Link to="/pins/123" state={{ fromDashboard: true }} />
let navigate = useNavigate();
navigate("/users/123", { state: partialUser });
復(fù)制代碼在目標(biāo)的組件中,可以用 useLocation 方法獲取該對象
let location = useLocation(); console.log(location.state);
state中的信息會進(jìn)行序列化,因此如日期對象等信息會變?yōu)閟tring
key
每個Location對象擁有一個唯一的key,可以據(jù)此來實(shí)現(xiàn)基于Location的滾動管理,或是數(shù)據(jù)緩存。
如:將 location.key 和 URL 作為鍵,每次請求數(shù)據(jù)前,先查找緩存是否存在來判斷是否實(shí)際發(fā)送請求,來實(shí)現(xiàn)客戶端數(shù)據(jù)緩存。
十一、 各類Router組件
11.1 HashRouter和BrowserRouter的區(qū)別
HashRouter只會修改URL中的哈希值部分;而BrowserRouter修改的是URL本身HashRouter是純前端路由,可以通過輸入URL直接訪問;使用時BrowserRouter直接輸入URL會顯示404,除非配置Nginx將請求指向?qū)?yīng)的HTML文件。初次進(jìn)入/路徑時或點(diǎn)擊Link組件跳轉(zhuǎn)時不會發(fā)送請求
11.2 unstable_HistoryRouter
使用 unstable_HistoryRouter 需要傳入一個 history 庫的實(shí)例,這將允許在非react作用于下操作history對象。
由于項(xiàng)目使用的history和react-router中使用的history版本可能不一樣,該API目前標(biāo)為unstable狀態(tài)
11.3 MemoryRouter
HashRouter 和 BrowserRouter 都是依據(jù)外部對象(history)進(jìn)行導(dǎo)航,而 MemoryRouter 則是自己存儲和管理狀態(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對象定義路由:useRoutes
使用 useRoutes hook,可以使用一個JS對象而不是Routes組件與Route組件來定義路由。其功能類似于react-router-config
useRoutes 的返回是 React Element,或是 null。
對于傳入的配置對象, 其類型定義如下:
interface RouteObject {
caseSensitive?: boolean;
children?: RouteObject[];
element?: React.ReactNode;
index?: boolean;
path?: string;
}到此這篇關(guān)于react-router-dom v6 使用詳細(xì)示例的文章就介紹到這了,更多相關(guān)react-router-dom v6 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React?Native?加載H5頁面的實(shí)現(xiàn)方法
這篇文章主要介紹了React?Native?加載H5頁面的實(shí)現(xiàn)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
前端 react 實(shí)現(xiàn)圖片上傳前壓縮(縮率圖)
這篇文章主要介紹了前端 react 實(shí)現(xiàn)圖片上傳前壓縮(縮率圖),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08
基于React Native 0.52實(shí)現(xiàn)輪播圖效果
這篇文章主要為大家詳細(xì)介紹了基于React Native 0.52實(shí)現(xiàn)輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-11-11
React中映射一個嵌套數(shù)組實(shí)現(xiàn)demo
這篇文章主要為大家介紹了React中映射一個嵌套數(shù)組實(shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
React實(shí)現(xiàn)一個拖拽排序組件的示例代碼
這篇文章主要給大家介紹了React實(shí)現(xiàn)一個拖拽排序組件?-?支持多行多列、支持TypeScript、支持Flip動畫、可自定義拖拽區(qū)域,文章通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11

