React 第五十三節 Router中 useRouteError 的使用詳解和案例分析

前言

useRouteErrorReact Router v6.4+ 引入的關鍵錯誤處理鉤子,用于在 路由錯誤邊界Error Boundary) 中獲取路由操作過程中發生的錯誤信息。
它提供了優雅的錯誤處理機制,讓開發者能夠創建用戶友好的錯誤界面。

一、useRouteError 核心用途

1.1、錯誤捕獲:

獲取路由加載、渲染或數據提交過程中發生的錯誤

1.2、錯誤展示:

在錯誤邊界組件中顯示有意義的錯誤信息

1.3、錯誤恢復:

提供錯誤恢復機制(如重試按鈕)

1.4、錯誤分類:

根據錯誤類型顯示不同的UI界面

二、useRouteError 基本用法示例

import { useRouteError } from 'react-router-dom';function ErrorPage() {const error = useRouteError();return (<div id="error-page"><h1>哎呀!出錯了</h1><p>抱歉,發生了一個意外的錯誤。</p><p><i>{error.statusText || error.message}</i></p></div>);
}

三、useRouteError 實際應用場景

3.1、基本錯誤邊界組件

import { useRouteError, isRouteErrorResponse } from 'react-router-dom';export function ErrorBoundary() {const error = useRouteError();// 檢查是否為路由錯誤響應if (isRouteErrorResponse(error)) {return (<div className="error-container"><h1 className="error-title">{error.status} {error.statusText}</h1><p className="error-message">{error.data}</p>{error.status === 404 && (<Link to="/" className="home-link">返回首頁</Link>)}</div>);}// 處理其他類型的錯誤return (<div className="error-container"><h1 className="error-title">未知錯誤</h1><p className="error-message">{error.message || '發生了一個未知錯誤'}</p><button className="retry-btn"onClick={() => window.location.reload()}>重試</button></div>);
}

3.2、分層錯誤邊界

// 根錯誤邊界 - 應用級別錯誤
export function RootErrorBoundary() {const error = useRouteError();return (<div className="fullscreen-error"><div className="error-card"><h1>應用錯誤</h1><p>抱歉,整個應用出現了問題</p><ErrorDetails error={error} /><div className="actions"><button onClick={() => window.location.reload()}>刷新應用</button><a href="/">返回首頁</a></div></div></div>);
}// 路由級別錯誤邊界
export function RouteErrorBoundary() {const error = useRouteError();return (<div className="route-error"><h2>頁面錯誤</h2><ErrorDetails error={error} /><div className="actions"><button onClick={() => window.history.back()}>返回上一頁</button></div></div>);
}// 錯誤詳情組件
function ErrorDetails({ error }) {return (<div className="error-details"><p><strong>錯誤信息:</strong> {error.message}</p>{isRouteErrorResponse(error) && (<p><strong>狀態碼:</strong> {error.status}</p>)}{error.stack && (<details className="stack-trace"><summary>查看技術細節</summary><pre>{error.stack}</pre></details>)}</div>);
}

3.3、在路由配置中使用錯誤邊界

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import {RootLayout,Dashboard,UserProfile,Settings,RootErrorBoundary,RouteErrorBoundary
} from './components';const router = createBrowserRouter([{path: '/',element: <RootLayout />,errorElement: <RootErrorBoundary />, // 應用級錯誤邊界children: [{index: true,element: <Dashboard />},{path: 'profile/:userId',element: <UserProfile />,errorElement: <RouteErrorBoundary />, // 路由級錯誤邊界loader: userProfileLoader // 可能拋出錯誤的loader},{path: 'settings',element: <Settings />,errorElement: <RouteErrorBoundary />,action: settingsAction // 可能拋出錯誤的action}]}
]);function App() {return <RouterProvider router={router} />;
}

3.4、自定義錯誤類型處理

import { useRouteError } from 'react-router-dom';export function ApiErrorBoundary() {const error = useRouteError();// 處理API錯誤if (error.name === 'ApiError') {return (<div className="api-error"><h2>API 請求失敗</h2><p>錯誤代碼: {error.code}</p><p>{error.message}</p>{error.code === 401 ? (<button onClick={() => location.href = '/login'}>重新登錄</button>) : (<button onClick={() => window.location.reload()}>重試</button>)}</div>);}// 處理路由錯誤響應if (isRouteErrorResponse(error)) {switch (error.status) {case 404:return <NotFoundError error={error} />;case 403:return <ForbiddenError error={error} />;case 500:return <ServerError error={error} />;default:return <GenericHttpError error={error} />;}}// 默認錯誤處理return <GenericError error={error} />;
}// 404錯誤組件
function NotFoundError({ error }) {return (<div className="not-found"><h1>頁面未找到</h1><p>您訪問的頁面不存在</p><p>錯誤信息: {error.data || error.statusText}</p><Link to="/" className="home-link">返回首頁</Link></div>);
}// 403錯誤組件
function ForbiddenError({ error }) {return (<div className="forbidden"><h1>權限不足</h1><p>您沒有權限訪問此內容</p><div className="actions"><button onClick={() => window.history.back()}>返回上一頁</button><Link to="/contact">聯系管理員</Link></div></div>);
}

3.5、結合加載器的錯誤處理

// 用戶詳情頁loader
export async function userLoader({ params }) {try {const user = await fetchUser(params.userId);if (!user) {// 拋出404錯誤響應throw new Response('用戶未找到', {status: 404,statusText: 'Not Found'});}return user;} catch (error) {// 拋出自定義API錯誤throw new ApiError({message: '加載用戶數據失敗',code: error.status || 500,originalError: error});}
}// 自定義API錯誤類
export class ApiError extends Error {constructor({ message, code, originalError }) {super(message);this.name = 'ApiError';this.code = code;this.originalError = originalError;// 保留原始堆棧跟蹤if (originalError?.stack) {this.stack = originalError.stack;}}
}

四、useRouteError 高級用法:錯誤恢復機制

import { useRouteError, useNavigate } from 'react-router-dom';export function RecoverableErrorBoundary() {const error = useRouteError();const navigate = useNavigate();const [retryCount, setRetryCount] = useState(0);const handleRetry = () => {setRetryCount(c => c + 1);navigate('.'); // 重新加載當前路由};const handleBack = () => {navigate(-1); // 返回上一頁};return (<div className="recoverable-error"><h1>發生錯誤</h1><p>{error.message || '請稍后再試'}</p><div className="error-actions"><button onClick={handleRetry} className="retry-btn">重試 {retryCount > 0 && `(${retryCount})`}</button><button onClick={handleBack} className="back-btn">返回</button></div>{retryCount > 2 && (<div className="advanced-options"><p>多次重試失敗?</p><button onClick={() => window.location.reload()}>刷新整個頁面</button><Link to="/support">聯系支持</Link></div>)}</div>);
}

五、useRouteError 錯誤類型處理指南

錯誤類型 識別方法 推薦處理方式
404 Not Found: error.status === 404; 顯示"未找到"頁面,提供返回首頁鏈接
403 Forbidden: error.status === 403; 顯示權限不足信息,提供登錄或聯系管理員選項
500 Server Error:error.status === 500;顯示服務器錯誤,提供重試或聯系支持選項
網絡錯誤 :error instanceof TypeError; 顯示連接問題,檢查網絡并提供重試
自定義錯誤: 自定義錯誤類; 根據業務邏輯定制錯誤處理
未捕獲異常: 其他所有錯誤; 顯示通用錯誤信息,提供技術細節

六、useRouteError 最佳實踐

6.1、分層錯誤邊界:

應用級:捕獲整個應用的意外錯誤

路由級:處理特定路由的錯誤

組件級:處理局部UI錯誤

6.2、用戶友好信息:

避免顯示技術性錯誤信息給普通用戶

提供清晰的恢復操作指引

為開發環境保留詳細錯誤日志

6.3、錯誤恢復機制:

提供重試按鈕

實現返回上一頁功能

添加刷新頁面選項

6.4、錯誤日志記錄:

    useEffect(() => {if (error) {logErrorToService(error);}}, [error]);

6.5、開發環境增強:

function ErrorDetails({ error }) {return (<div>{process.env.NODE_ENV === 'development' && (<details><summary>開發人員詳情</summary><pre>{error.stack}</pre></details>)}</div>);
}

七、useRouteError 注意事項

7.1、錯誤邊界位置:

錯誤邊界必須位于路由層級中

只能捕獲其子組件樹中的錯誤

7.2、錯誤類型檢查:

使用 isRouteErrorResponse 檢查路由錯誤響應

處理各種可能的錯誤類型

7.3、異步錯誤處理:

loader/action 中的異步錯誤會被自動捕獲

組件中的錯誤需要使用 useRouteError 獲取

7.4、錯誤傳播:

錯誤會向上傳播到最近的錯誤邊界

未被捕獲的錯誤會導致應用崩潰

7.5、與React錯誤邊界結合:

class ReactErrorBoundary extends React.Component {state = { hasError: false };static getDerivedStateFromError() {return { hasError: true };}render() {if (this.state.hasError) {return <RouterErrorBoundary />;}return this.props.children;}
}

總結

useRouteErrorReact Router v6.4+ 錯誤處理機制的核心,可以幫助我們實現如下場景:

  1. 創建用戶友好的錯誤界面
  2. 實現分層錯誤處理策略
  3. 根據錯誤類型提供定制化UI
  4. 實現錯誤恢復和重試機制
  5. 結合路由加載器和動作進行錯誤處理

通過合理使用 useRouteError,我們可以顯著提升應用的健壯性和用戶體驗,確保即使發生錯誤,用戶也能獲得清晰的反饋和恢復路徑。

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

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

相關文章

[arthas]arthas安裝使用

arthas是阿里開源的一個java線上監控以及診斷工具&#xff0c;在docker容器中我們無需重啟服務&#xff0c;也不用更改代碼&#xff0c;就可以完成對應用內存、線程、日志級別的修改、方法調用的出入參、異常監測、執行耗時等&#xff0c;xxxx.xxxx.xxxxx為脫敏內容 1. 在docke…

Flask-Babel 使用示例

下面創建一個簡單的 Flask-Babel 示例&#xff0c;展示如何在 Flask 應用中實現國際化和本地化功能。這個示例將包括多語言支持&#xff08;中文和英文&#xff09;、語言切換功能以及翻譯文本的使用。 項目結構 我們將創建以下文件結構&#xff1a; 1. 首先&#xff0c;創…

[論文閱讀] 軟件工程 | 量子計算如何賦能軟件工程(Quantum-Based Software Engineering)

arXiv:2505.23674 [pdf, html, other] Quantum-Based Software Engineering Jianjun Zhao Subjects: Software Engineering (cs.SE); Quantum Physics (quant-ph) 量子計算如何賦能軟件工程 我們在開發軟件時&#xff0c;常常會遇到一些棘手的問題。比如&#xff0c;為了確保軟…

Ansible 進階 - Roles 與 Inventory 的高效組織

Ansible 進階 - Roles 與 Inventory 的高效組織 如果說 Playbook 是一份完整的“菜譜”,那么 Role (角色) 就可以被看作是制作這道菜(或一桌菜)所需的標準化“備料包”或“半成品組件”。例如,我們可以有一個“Nginx Web 服務器安裝配置 Role”、“MySQL 數據庫基礎設置 Ro…

青少年編程與數學 01-011 系統軟件簡介 04 Linux操作系統

青少年編程與數學 01-011 系統軟件簡介 04 Linux操作系統 一、Linux 的發展歷程&#xff08;一&#xff09;起源&#xff08;二&#xff09;早期發展&#xff08;三&#xff09;成熟與普及&#xff08;四&#xff09;移動與嵌入式領域的拓展 二、Linux 的內核與架構&#xff08…

將圖形可視化工具的 Python 腳本打包為 Windows 應用程序

前文我們已經寫了一個基于python的tkinter庫和matplotlib庫的圖形可視化工具。 基于Python的tkinter庫的圖形可視化工具&#xff08;15種圖形的完整代碼&#xff09;:基于Python的tkinter庫的圖形可視化工具&#xff08;15種圖形的完整代碼&#xff09;-CSDN博客 在前文基礎上&…

【Kotlin】簡介變量類接口

【Kotlin】簡介&變量&類&接口 【Kotlin】數字&字符串&數組&集合 【Kotlin】高階函數&Lambda&內聯函數 【Kotlin】表達式&關鍵字 文章目錄 Kotlin_簡介&變量&類&接口Kotlin的特性Kotlin優勢創建Kotlin項目變量變量保存了指向對…

OpenCV種的cv::Mat與Qt種的QImage類型相互轉換

一、首先了解cv::Mat結構體 cv::Mat::step與QImage轉換有著較大的關系。 step的幾個類別區分: step:矩陣第一行元素的字節數step[0]:矩陣第一行元素的字節數step[1]:矩陣中一個元素的字節數step1(0):矩陣中一行有幾個通道數step1(1):一個元素有幾個通道數(channel()) cv::Ma…

搭建基于VsCode的ESP32的開發環境教程

一、VsCode搜索ESP-IDF插件 根據插件處搜索找到ESP-IDF并安裝 安裝完成 二、配置安裝ESP-IDF 配置IDF 按照如下配置&#xff0c;點擊安裝 安裝完成 三、使用案例程序 創建一個閃光燈的例子程序&#xff0c;演示程序編譯下載。 選擇blink例子&#xff0c;閃爍LED的程序 選…

企業培訓學習考試系統源碼 ThinkPHP框架+Uniapp支持多終端適配部署

在數字化轉型浪潮下&#xff0c;企業對高效培訓與精準考核的需求日益迫切。一套功能完備、多終端適配且易于定制的培訓學習考試系統&#xff0c;成為企業提升員工能力、檢驗培訓成果的關鍵工具。本文給大家分享一款基于 ThinkPHP 框架與 Uniapp 開發的企業培訓學習考試系統&…

【PmHub面試篇】PmHub集成Redission分布式鎖保障流程狀態更新面試專題解析

你好&#xff0c;歡迎來到本次關于PmHub整合TransmittableThreadLocal (TTL)緩存用戶數據的面試系列分享。在這篇文章中&#xff0c;我們將深入探討這一技術領域的相關面試題預測。若想對相關內容有更透徹的理解&#xff0c;強烈推薦參考之前發布的博文&#xff1a;【PmHub后端…

mac 設置cursor (像PyCharm一樣展示效果)

一、注冊 Cursor - The AI Code Editor 二、配置Python環境 我之前使用pycharm創建的python項目&#xff0c;以及創建了虛擬環境&#xff0c;現在要使用cursor繼續開發。 2.1 選擇Python 虛擬環境 PyCharm 通常將虛擬環境存儲在項目目錄下的 venv 或 .venv 文件夾中&#xf…

Spring事務失效-----十大常見場景及解決方案全解析

Spring事務失效的常見場景及原因分析 Spring事務管理是開發中的核心功能,但在實際應用中可能因各種原因導致事務失效。以下是常見的事務失效場景及詳細解析: 1. 方法未被Spring管理 場景:使用new關鍵字直接創建對象,而非通過Spring容器注入原因:Spring事務基于AOP代理,…

剛出爐熱乎的。UniApp X 封裝 uni.request

HBuilder X v4.66 當前最新版本 由于 uniapp x 使用的是自己包裝的 ts 語言 uts。目前語言還沒有穩定下來&#xff0c;各種不支持 ts 各種報錯各種不兼容問題。我一個個問題調通的&#xff0c;代碼如下&#xff1a; 封裝方法 // my-app/utils/request.uts const UNI_APP_BASE…

【ArcGIS微課1000例】0148:Geographic Imager6.2使用教程

文章目錄 一、Geographic Imager6.2下載安裝二、Geographic Imager6.2使用方法1. 打開Geographic Imager2. 導入地理影像3. 導入DEM地形渲染4. 設置地理坐標系統5. 進行地理影像的處理6. 導出地理影像一、Geographic Imager6.2下載安裝 在專欄上一篇文章中已經詳細講述了Geogr…

零基礎安裝 Python 教程:從下載到環境配置一步到位(支持 VSCode 和 PyCharm)與常用操作系統操作指南

零基礎安裝 Python 教程&#xff1a;從下載到環境配置一步到位&#xff08;支持 VSCode 和 PyCharm&#xff09;與常用操作系統操作指南 本文是一篇超詳細“Python安裝教程”&#xff0c;覆蓋Windows、macOS、Linux三大操作系統的Python安裝方法與環境配置&#xff0c;包括Pyt…

定時任務的 cron 表達式

定時任務的 cron 表達式 一、什么時 cron 表達式 Cron表達式是一種廣泛應用于Linux系統的時間表示格式&#xff0c;常用于定時任務的調度。Cron表達式可以通過指定不同的時間參數&#xff0c;描述一個在 未來某個時間點執行的任務。 二、Cron表達式語法 秒 分 時 日 月 周幾…

PHP+mysql 美容美發預約小程序源碼 支持DIY裝修+完整圖文搭建教程

在數字化浪潮席卷的當下&#xff0c;美容美發行業也急需線上轉型&#xff0c;以提升客戶預約效率與服務體驗。開發一款美容美發預約小程序成為眾多商家的迫切需求。本文將為大家分享一套基于 PHPMySQL 的美容美發預約小程序源碼&#xff0c;功能完備、支持 DIY 裝修&#xff0c…

十八、【用戶認證篇】安全第一步:基于 JWT 的前后端分離認證方案

【用戶認證篇】安全第一步:基于 JWT 的前后端分離認證方案 前言什么是 JWT (JSON Web Token)?準備工作第一部分:后端 Django 配置 JWT 認證1. 安裝 `djangorestframework-simplejwt`2. 在 `settings.py` 中配置 `djangorestframework-simplejwt`3. 在項目的 `urls.py` 中添加…

03 Deep learning神經網絡的編程基礎 代價函數(Cost function)--吳恩達

深度學習中的損失函數(Cost Function)用于量化模型預測與真實數據的差距,是優化神經網絡的核心指標。以下是常見類型及數學表達: 核心原理 邏輯回歸通過sigmoid函數將線性預測結果轉換為概率: y ^ ( i ) \hat{y}^{(i)}