HOW - React Router v6.x Feature 實踐(react-router-dom)

目錄

  • 基本特性
  • ranked routes matching
  • active links
    • NavLink
    • useMatch
  • relative links
      • 1. 相對路徑的使用
      • 2. 嵌套路由的增強行為
      • 3. 優勢和注意事項
      • 4. . 和 ..
      • 5. 總結
  • data loading
  • loading or changing data and redirect
  • pending navigation ui
  • skeleton ui with suspense
  • data mutations with `<Route action>`
  • busy indicators with route actions
  • data fetchers

基本特性

  1. client side routing
  2. nested routes
  3. dynamic segments

比較好理解,這里不贅述。

ranked routes matching

https://reactrouter.com/en/main/start/overview#ranked-route-matching

When matching URLs to routes, React Router will rank the routes according to the number of segments, static segments, dynamic segments, splats, etc. and pick the most specific match.

這句話描述了 React Router 在匹配 URL 和路由時的策略,即根據路由的具體性來優先選擇最合適的匹配項。讓我們逐步解析這句話的含義:

  1. URL 和路由的匹配

    • 當用戶訪問某個 URL 時,React Router 需要確定哪個路由規則最適合處理該 URL。例如,對于 URL /users/123,React Router 需要決定是匹配 /users/:id 還是其他定義的路由。
  2. 路由匹配的考量因素:優先級由高到低

    • 路由的段數(Segments):URL 和路由可以分成多個段(segments),例如 /users/123 有兩個段,/users/:id 也有兩個段。React Router 會比較 URL 和每個路由的段數,越多的段數一般意味著路由更具體。

    • 靜態段(Static Segments):靜態段是指在路由中直接指定的固定路徑,例如 /users 是一個靜態段。React Router 會考慮靜態段的數量來確定路由的具體性。

    • 動態段(Dynamic Segments):動態段是指在路由中使用參數化路徑,例如 /users/:id 中的 :id 是一個動態段。動態段的存在可能使得路由更靈活但也更具體。

    • 通配符(Splat):通配符(如 *)表示匹配多個路徑段,通常用于處理不確定數量的路徑部分。

  3. 最具體的匹配

    • React Router 會通過比較以上因素來確定哪個路由定義是最具體的匹配。具體的路由定義意味著它能夠最準確地匹配當前的 URL,而不會與其他可能的路由定義沖突。
  4. 示例

<Route path="/teams/:teamId" />
<Route path="/teams/new" />

對于 http://example.com/teams/new. 會優先匹配第二個 Route。因為靜態段數為 2,更具體。

理解 React Router 的路由匹配策略,特別是根據路由的具體性來優先選擇最合適的匹配項,有助于開發者更有效地設計和管理復雜的路由結構。通過正確的路由定義和優先級排序,可以確保應用程序在導航和頁面渲染時行為符合預期,并能夠靈活地應對各種場景和URL路徑。

active links

NavLink

https://reactrouter.com/en/main/components/nav-link

<NavLinkstyle={({ isActive, isPending }) => {return {color: isActive ? "red" : "inherit",};}}className={({ isActive, isPending }) => {return isActive ? "active" : isPending ? "pending" : "";}}
/>

useMatch

https://reactrouter.com/en/main/hooks/use-match

function SomeComp() {const match = useMatch("/messages");return <li className={Boolean(match) ? "active" : ""} />;
}

relative links

理解 React Router 中 <Link><NavLink> 組件相對路徑的使用需要考慮它們與 HTML 中 <a> 標簽的行為差異,尤其是在嵌套路由場景下的增強行為。

1. 相對路徑的使用

  • HTML <a> 標簽:在 HTML 中,使用 <a> 標簽時,相對路徑通常相對于當前頁面的完整 URL。這意味著,相對路徑會根據當前頁面的路徑來構建最終的目標 URL。

    <a href="about">About</a>
    
    • 如果當前 URL 是 http://example.com/home,那么點擊上述鏈接將導航到 http://example.com/about
  • React Router 中的 <Link><NavLink>:在 React Router 中,<Link><NavLink> 組件可以接受相對路徑,但它們的行為略有不同。

    import { Link, NavLink } from 'react-router-dom';<Link to="about">About</Link>
    <NavLink to="about">About</NavLink>
    
    • 這里的 to="about" 是相對路徑,相對于當前路由的路徑來構建目標 URL。例如,如果當前路由是 /home,那么這兩個鏈接將會導航到 /home/about

2. 嵌套路由的增強行為

  • 嵌套路由:當應用程序中存在嵌套路由時,React Router 的 <Link><NavLink> 組件表現出更智能的行為,確保相對路徑的正確解析。

    <Route path="/home"><Link to="about">About</Link><NavLink to="about">About</NavLink>
    </Route>
    
    • 在上述例子中,假設當前路由是 /home,那么 <Link><NavLink> 組件會基于當前路由的路徑 /home 構建相對路徑,導航到 /home/about

3. 優勢和注意事項

  • 靈活性和便利性:相對路徑的使用使得在應用中鏈接管理更加靈活和簡單,尤其是在處理嵌套路由時。

  • 注意路徑解析:確保理解相對路徑在不同嵌套層級下的解析規則。React Router 的行為通常是基于當前活動的路由來解析相對路徑,而不是簡單地相對于根路徑

4. . 和 …

<Route path="/home"><Link to=".">About</Link><NavLink to=".">About</NavLink>
</Route>
  • 在上述例子中,假設當前路由是 /home,那么 <Link><NavLink> 組件會基于當前路由的路徑 /home 構建相對路徑,導航到 /home
<Route path="home" element={<Home />}><Route path="project/:projectId" element={<Project />}><Route path=":taskId" element={<Task />} /></Route>
</Route>

Project 中會渲染:

  <Link to="abc"><Link to="."><Link to=".."></Link><Link to=".." relative="path">
  • 在上述例子中,假設當前路由是 /home/project/123,那么 <Link> 會基于當前路由的路徑構建相對路徑,分別導航到 /home/project/123/abc/home/project/abc/home/home/project

注意后面兩個的差異:

By default, the … in relative links traverse the route hierarchy, not the URL segments. Adding relative=“path” in the next example allows you to traverse the path segments instead.

5. 總結

理解 React Router 中 <Link><NavLink> 組件相對路徑的行為,特別是在嵌套路由情況下的增強行為,有助于開發者更有效地管理和導航應用程序中的鏈接。相對路徑的使用使得在不同層級和場景下的導航操作更加靈活和便捷,但需要注意理解和控制路徑的解析和構建規則。

data loading

https://reactrouter.com/en/main/start/overview#data-loading

Combined with nested routes, all of the data for multiple layouts at a specific URL can be loaded in parallel.

<Routepath="/"loader={async ({ request }) => {// loaders can be async functionsconst res = await fetch("/api/user.json", {signal: request.signal,});const user = await res.json();return user;}}element={<Root />}
><Routepath=":teamId"// loaders understand Fetch Responses and will automatically// unwrap the res.json(), so you can simply return a fetchloader={({ params }) => {return fetch(`/api/teams/${params.teamId}`);}}element={<Team />}><Routepath=":gameId"loader={({ params }) => {// of course you can use any data storereturn fakeSdk.getTeam(params.gameId);}}element={<Game />}/></Route>
</Route>

Data is made available to your components through useLoaderData.

function Root() {const user = useLoaderData();// data from <Route path="/">
}function Team() {const team = useLoaderData();// data from <Route path=":teamId">
}function Game() {const game = useLoaderData();// data from <Route path=":gameId">
}

When the user visits or clicks links to https://example.com/real-salt-lake/45face3, all three route loaders will be called and loaded in parallel, before the UI for that URL renders.

loading or changing data and redirect

https://reactrouter.com/en/main/route/loader#throwing-in-loaders

<Routepath="dashboard"loader={async () => {const user = await fake.getUser();if (!user) {// if you know you can't render the route, you can// throw a redirect to stop executing code here,// sending the user to a new routethrow redirect("/login");}// otherwise continueconst stats = await fake.getDashboardStats();return { user, stats };}}
/>

pending navigation ui

https://reactrouter.com/en/main/start/overview#pending-navigation-ui

When users navigate around the app, the data for the next page is loaded before the page is rendered. It’s important to provide user feedback during this time so the app doesn’t feel like it’s unresponsive.

function Root() {const navigation = useNavigation();return (<div>{navigation.state === "loading" && <GlobalSpinner />}<FakeSidebar /><Outlet /><FakeFooter /></div>);
}

skeleton ui with suspense

https://reactrouter.com/en/main/start/overview#skeleton-ui-with-suspense

Instead of waiting for the data for the next page, you can defer data so the UI flips over to the next screen with placeholder UI immediately while the data loads.

defer enables suspense for the un-awaited promises

<Routepath="issue/:issueId"element={<Issue />}loader={async ({ params }) => {// these are promises, but *not* awaitedconst comments = fake.getIssueComments(params.issueId);const history = fake.getIssueHistory(params.issueId);// the issue, however, *is* awaitedconst issue = await fake.getIssue(params.issueId);// defer enables suspense for the un-awaited promisesreturn defer({ issue, comments, history });}}
/>;function Issue() {const { issue, history, comments } = useLoaderData();return (<div><IssueDescription issue={issue} />{/* Suspense provides the placeholder fallback */}<Suspense fallback={<IssueHistorySkeleton />}>{/* Await manages the deferred data (promise) */}<Await resolve={history}>{/* this calls back when the data is resolved */}{(resolvedHistory) => (<IssueHistory history={resolvedHistory} />)}</Await></Suspense><Suspense fallback={<IssueCommentsSkeleton />}><Await resolve={comments}>{/* ... or you can use hooks to access the data */}<IssueComments /></Await></Suspense></div>);
}function IssueComments() {const comments = useAsyncValue();return <div>{/* ... */}</div>;
}

涉及如下 API 結合使用:

  1. defer
  2. Await
  3. useAsyncValue

data mutations with <Route action>

https://reactrouter.com/en/main/start/overview#data-mutations

HTML forms are navigation events, just like links. React Router supports HTML form workflows with client side routing.

When a form is submitted, the normal browser navigation event is prevented and a Request, with a body containing the FormData of the submission, is created. This request is sent to the <Route action> that matches the form’s <Form action>.

Form elements’s name prop are submitted to the action:

<Form action="/project/new"><label>Project title<br /><input type="text" name="title" /></label><label>Target Finish Date<br /><input type="date" name="due" /></label>
</Form>
<Routepath="project/new"action={async ({ request }) => {const formData = await request.formData();const newProject = await createProject({title: formData.get("title"),due: formData.get("due"),});return redirect(`/projects/${newProject.id}`);}}
/>

在 HTML 中,<form> 元素的 action 屬性定義了當用戶提交表單時將數據發送到的服務器端的 URL。

具體來說:

  • action 屬性的作用

    • 當用戶提交表單時,瀏覽器會將表單中的數據發送到指定的 URL。
    • 這個 URL 可以是相對路徑或絕對路徑。
    • 如果 action 屬性未指定,表單會被提交到當前頁面的 URL(即自身)。
  • 使用示例

    <form action="/project/new" method="post"><!-- 表單內容 --><input type="text" name="project_name" /><button type="submit">提交</button>
    </form>
    
    • 在這個例子中,action 屬性的值是 "/project/new"。當用戶點擊提交按鈕時,表單數據將被發送到當前服務器的 /project/new 路徑。
  • 重要說明

    • 如果 action 屬性指向一個相對路徑,表單數據會被提交到當前頁面的基礎 URL 加上 action 的值。
    • 如果 action 屬性是絕對路徑(例如 http://example.com/project/new),數據將被發送到指定的絕對路徑。
  • HTTP 方法 (method 屬性)

    • 另一個與 action 相關的重要屬性是 method,它指定了使用何種 HTTP 方法將表單數據發送到服務器。
    • 常見的方法是 GETPOSTGET 方法將數據附加到 URL 上(可見),而 POST 方法將數據包含在請求體中(不可見)。

總結來說,action 屬性定義了表單數據提交的目標 URL。這對于將用戶輸入數據發送到后端處理或其他指定的處理程序非常重要。

busy indicators with route actions

https://reactrouter.com/en/main/start/overview#busy-indicators

When forms are being submitted to route actions, you have access to the navigation state to display busy indicators, disable fieldsets, etc.

function NewProjectForm() {const navigation = useNavigation();const busy = navigation.state === "submitting";return (<Form action="/project/new"><fieldset disabled={busy}><label>Project title<br /><input type="text" name="title" /></label><label>Target Finish Date<br /><input type="date" name="due" /></label></fieldset><button type="submit" disabled={busy}>{busy ? "Creating..." : "Create"}</button></Form>);
}

data fetchers

HTML Forms are the model for mutations but they have one major limitation: you can have only one at a time because a form submission is a navigation.

Most web apps need to allow for multiple mutations to be happening at the same time, like a list of records where each can be independently deleted, marked complete, liked, etc.

Fetchers allow you to interact with the route actions and loaders without causing a navigation in the browser, but still getting all the conventional benefits like error handling, revalidation, interruption handling, and race condition handling.

Imagine a list of tasks:

function Tasks() {const tasks = useLoaderData();return tasks.map((task) => (<div><p>{task.name}</p><ToggleCompleteButton task={task} /></div>));
}

Each task can be marked complete independently of the rest, with its own pending state and without causing a navigation with a fetcher:

function ToggleCompleteButton({ task }) {const fetcher = useFetcher();return (<fetcher.Form method="post" action="/toggle-complete"><fieldset disabled={fetcher.state !== "idle"}><input type="hidden" name="id" value={task.id} /><inputtype="hidden"name="status"value={task.complete ? "incomplete" : "complete"}/><button type="submit">{task.status === "complete"? "Mark Incomplete": "Mark Complete"}</button></fieldset></fetcher.Form>);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41122.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JAVA高級進階11多線程

第十一天、多線程 線程安全問題 線程安全問題 多線程給我們帶來了很大性能上的提升,但是也可能引發線程安全問題 線程安全問題指的是當個多線程同時操作同一個共享資源的時候,可能會出現的操作結果不符預期問題 線程同步方案 認識線程同步 線程同步 線程同步就是讓多個線…

內網滲透學習-殺入內網

1、靶機上線cs 我們已經拿到了win7的shell&#xff0c;執行whoami&#xff0c;發現win7是administrator權限&#xff0c;且在域中 執行ipconfig發現了win7存在內網網段192.168.52.0/24 kali開啟cs服務端 客戶端啟動cs 先在cs中創建一個監聽器 接著用cs生成后門&#xff0c;記…

Mysql 的第二次作業

一、數據庫 1、登陸數據庫 2、創建數據庫zoo 3、修改數據庫zoo字符集為gbk 4、選擇當前數據庫為zoo 5、查看創建數據庫zoo信息 6、刪除數據庫zoo 1&#xff09;登陸數據庫。 打開命令行&#xff0c;輸入登陸用戶名和密碼。 mysql -uroot -p123456 ? 2&#xff09;切換數據庫…

菜雞的原地踏步史(???)

leetcode啟動&#xff01;(╯‵□′)╯︵┻━┻ 嘗試改掉想到哪寫哪的代碼壞習慣 鏈表 相交鏈表 public class Solution {/**ac&#xff08;公共長度&#xff09;b所以 鏈表A的長度 a c&#xff0c;鏈表B的長度b ca b c b c a只要指針a從headA開始走&#xff0c;走完再…

利用pg_rman進行備份與恢復操作

文章目錄 pg_rman簡介一、安裝配置pg_rman二、創建表與用戶三、備份與恢復 pg_rman簡介 pg_rman 是 PostgreSQL 的在線備份和恢復工具。類似oracle 的 rman pg_rman 項目的目標是提供一種與 pg_dump 一樣簡單的在線備份和 PITR 方法。此外&#xff0c;它還為每個數據庫集群維護…

抖音使矛,美團用盾

有市場&#xff0c;就有競爭。抖音全力進軍本地生活市場欲取代美團&#xff0c;已不是新聞。 互聯網行業進入存量時代&#xff0c;本地生活市場是為數不多存在較大增長空間的賽道。艾媒咨詢數據顯示&#xff0c;預計2025年在線餐飲外賣市場規模達到17469億元&#xff0c;生鮮電…

Day05-01-jenkins進階

Day05-01-jenkins進階 10. 案例07: 理解 案例06基于ans實現10.1 整體流程10.2 把shell改為Ansible劇本10.3 jk調用ansible全流程10.4 書寫劇本 11. Jenkins進階11.1 jenkins分布式1&#xff09;概述2&#xff09;案例08&#xff1a;拆分docker功能3&#xff09;創建任務并綁定到…

安裝 ClamAV 并進行病毒掃描

安裝 ClamAV 并進行病毒掃描 以下是安裝 ClamAV 并使用它進行病毒掃描的步驟&#xff1a; 1. 安裝 ClamAV 在 Debian/Ubuntu 系統上&#xff1a; sudo apt update sudo apt install clamav clamav-daemon在 RHEL/CentOS 系統上&#xff1a; sudo yum install epel-release…

開發指南040-swagger加header

swagger可以在線生成接口文檔&#xff0c;便于前后端溝通&#xff0c;而且還可以在線調用接口&#xff0c;方便后臺調試。但是接口需要經過登錄校驗&#xff0c;部分接口還需要得到登錄token&#xff0c;使用token識別用戶身份進行后續操作。這種情況下&#xff0c;都需要接口增…

【刷題筆記(編程題)05】另類加法、走方格的方案數、井字棋、密碼強度等級

1. 另類加法 給定兩個int A和B。編寫一個函數返回AB的值&#xff0c;但不得使用或其他算數運算符。 測試樣例&#xff1a; 1,2 返回&#xff1a;3 示例 1 輸入 輸出 思路1: 二進制0101和1101的相加 0 1 0 1 1 1 0 1 其實就是 不帶進位的結果1000 和進位產生的1010相加 無進位加…

ssm校園志愿服務信息系統-計算機畢業設計源碼97697

摘 要 隨著社會的進步和信息技術的發展&#xff0c;越來越多的學校開始重視志愿服務工作&#xff0c;通過組織各種志愿服務活動&#xff0c;讓學生更好地了解社會、服務社會。然而&#xff0c;在實際操作中&#xff0c;志愿服務的組織和管理面臨著諸多問題&#xff0c;如志愿者…

dledger原理源碼分析系列(一)-架構,核心組件和rpc組件

簡介 dledger是openmessaging的一個組件&#xff0c; raft算法實現&#xff0c;用于分布式日志&#xff0c;本系列分析dledger如何實現raft概念&#xff0c;以及dledger在rocketmq的應用 本系列使用dledger v0.40 本文分析dledger的架構&#xff0c;核心組件&#xff1b;rpc組…

【pytorch16】MLP反向傳播

鏈式法則回顧 多輸出感知機的推導公式回顧 只與w相關的輸出節點和輸入節點有關 多層多輸入感知機 擴展為多層感知機的話&#xff0c;意味著還有一些層&#xff08;理解為隱藏層σ函數&#xff09;&#xff0c;暫且設置為 x j x_{j} xj?層 對于 x j x_{j} xj?層如果把前面的…

迅捷PDF編輯器合并PDF

迅捷PDF編輯器是一款專業的PDF編輯軟件&#xff0c;不僅支持任意添加文本&#xff0c;而且可以任意編輯PDF原有內容&#xff0c;軟件上方的工具欄中還有豐富的PDF標注、編輯功能&#xff0c;包括高亮、刪除線、下劃線這些基礎的&#xff0c;還有規則或不規則框選、箭頭、便利貼…

【護眼小知識】護眼臺燈真的護眼嗎?防近視臺燈有效果嗎?

當前&#xff0c;近視問題在人群中愈發普遍&#xff0c;據2024年的統計數據顯示&#xff0c;我國兒童青少年的總體近視率已高達52.7%。并且近視背后潛藏著諸多眼部并發癥的風險&#xff0c;例如視網膜脫離、白內障以及開角型青光眼等&#xff0c;嚴重的情況甚至可能引發失明。為…

PMP--知識卡片--波士頓矩陣

文章目錄 記憶黑話概念作用圖示 記憶 一說到波士頓就聯想到波士頓龍蝦&#xff0c;所以波士頓矩陣跟動物有關&#xff0c;狗&#xff0c;牛。 黑話 你公司的現金牛業務&#xff0c;正在逐漸變成瘦狗&#xff0c;應盡快采取收割策略&#xff1b;問題業務的儲備太少&#xff0…

必須掌握的Linux的九大命令

ifconfig 命令用于配置和查看網絡接口的參數。 ping 命令用于測試主機之間的網絡連通性。 telnet用于通過Telnet協議連接到遠程主機。 telnet 127.0.0.1 8000 telnet example.com telnet example.com 8080 iostat 命令用于報告 CPU 統計信息和 I/O 設備負載。 iostat&…

護眼熱點:臺燈護眼是真的嗎?一起來看臺燈的功能作用有哪些

如今近視問題日益嚴峻&#xff0c;尤為引人矚目的是&#xff0c;高度近視學生群體占比已逼近10%的警戒線&#xff0c;且這一比例伴隨著學齡的增長而悄然攀升——從幼兒園6歲孩童中那令人憂慮的1.5%&#xff0c;到高中階段驚人的17.6%&#xff0c;每一組數據都敲響了保護兒童視力…

【Linux】靜態庫的制作和使用詳解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;個人主頁 &#xff1a;阿然成長日記 …

代碼隨想錄算法訓練營第71天:路徑算法[1]

代碼隨想錄算法訓練營第71天&#xff1a;路徑算法 ? bellman_ford之單源有限最短路 卡碼網&#xff1a;96. 城市間貨物運輸 III(opens new window) 【題目描述】 某國為促進城市間經濟交流&#xff0c;決定對貨物運輸提供補貼。共有 n 個編號為 1 到 n 的城市&#xff0c…