有效的錯誤處理對於提供無縫的使用者體驗和維護乾淨、可擴展的程式碼至關重要。在複雜的應用程式中,跨元件手動管理錯誤通常會導致程式碼混亂且不一致。本指南將向您展示如何使用 Axios、自訂鉤子 (useApi) 和模組化服務層在 React 中建立模組化、可擴展且集中的錯誤處理系統,以建立使用者友好、有組織且高效的結構。
想像一下您正在建立一個電子商務平台。多個元件從不同的 API 取得數據,每個元件都可能因不同的原因而失敗——網路問題、伺服器錯誤或無效的使用者輸入。如果沒有集中的錯誤處理系統,您的程式碼就會因重複的錯誤檢查而變得混亂,並且使用者會收到不一致的回饋。如何簡化此流程以確保可靠性和無縫的使用者體驗?本指南將向您展示如何操作。
最後,您將學到:
集中式錯誤處理解決了兩個常見的挑戰:
使用 Axios 攔截器、自訂掛鉤 (useApi) 和服務模組的集中式方法可以透過以下方式解決這些問題:
Axios 攔截器是 Axios 對每個請求或回應呼叫的函數。透過設定回應攔截器,您可以全域處理錯誤、解析回應以及根據特定條件執行日誌記錄或重新導向使用者等操作。
第 1 步:導入必要的模組
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
第 2 步:建立 Axios 實例
const axiosInstance = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || '', headers: { 'Content-Type': 'application/json', }, });
第 3 步:新增回應攔截器
axiosInstance.interceptors.response.use( (response) => response, // Pass through successful responses (error) => { if (!error.response) { toast.error(ERROR_MESSAGES.NETWORK_ERROR); return Promise.reject(error); } const { status, data } = error.response; let message = ERROR_MESSAGES[status] || ERROR_MESSAGES.GENERIC_ERROR; // Custom logic for specific error types if (data?.type === 'validation') { message = `Validation Error: ${data.message}`; } else if (data?.type === 'authentication') { message = `Authentication Error: ${data.message}`; } // Display error notification toast.error(message); // Handle unauthorized access by redirecting to login if (status === 401) { Router.push('/login'); } return Promise.reject(error); } );
說明:
第 4 步:匯出 Axios 實例
export default axiosInstance;
在單獨的設定檔中定義自訂錯誤訊息,以保持一致性和易於管理。
// config/customErrors.js const ERROR_MESSAGES = { NETWORK_ERROR: "Network error. Please check your connection and try again.", BAD_REQUEST: "There was an issue with your request. Please check and try again.", UNAUTHORIZED: "You are not authorized to perform this action. Please log in.", FORBIDDEN: "Access denied. You don't have permission to view this resource.", NOT_FOUND: "The requested resource was not found.", GENERIC_ERROR: "Something went wrong. Please try again later.", // You can add more messages here if you want }; export default ERROR_MESSAGES;
設定 Axios 攔截器提供:
這個集中式 Axios 實例是建立可靠、使用者友好的 API 通訊層的關鍵,可確保跨應用程式對所有 API 請求和錯誤處理進行一致管理。
useApi 掛鉤集中 API 請求處理、管理載入、資料和錯誤狀態。透過抽象化這個過程,useApi 可以讓元件避免重複的 try-catch 區塊,而專注於資料呈現。
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
在深入研究之前,有必要了解 JavaScript 中的 Promise 和 Promise Rejection,因為它們在處理 API 呼叫等非同步操作中發揮關鍵作用。
如果沒有 useApi 鉤子,您將需要在每個進行 API 呼叫的元件中實作 try-catch 區塊。這種方法導致:
透過使用 useApi 鉤子,您可以抽像出重複的錯誤處理邏輯,從而促進更乾淨、更易於維護的程式碼。
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
在此範例中,useApi 掛鉤管理 API 呼叫以取得產品。它處理載入狀態,捕獲任何錯誤,並將獲取的資料提供給元件進行渲染。
服務模組定義 API 端點函數,依實體(例如使用者、產品)組織。這種結構使 API 邏輯與元件程式碼分離,確保模組化和重複使用。
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
const axiosInstance = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || '', headers: { 'Content-Type': 'application/json', }, });
對於那些準備進一步改進錯誤處理系統的人,請考慮實施這些先進技術:
將錯誤分類(例如網路與驗證)並提供可操作的訊息,以幫助使用者了解問題和可能的解決方案。
實作:
axiosInstance.interceptors.response.use( (response) => response, // Pass through successful responses (error) => { if (!error.response) { toast.error(ERROR_MESSAGES.NETWORK_ERROR); return Promise.reject(error); } const { status, data } = error.response; let message = ERROR_MESSAGES[status] || ERROR_MESSAGES.GENERIC_ERROR; // Custom logic for specific error types if (data?.type === 'validation') { message = `Validation Error: ${data.message}`; } else if (data?.type === 'authentication') { message = `Authentication Error: ${data.message}`; } // Display error notification toast.error(message); // Handle unauthorized access by redirecting to login if (status === 401) { Router.push('/login'); } return Promise.reject(error); } );
說明:
為失敗的請求實作重試選項,例如 UI 中的重試按鈕或具有指數退避的自動重試,以增強可靠性。
實作:
export default axiosInstance;
說明:
以嚴重性(訊息、警告、錯誤)區分通知,以幫助使用者了解錯誤的重要性。
實作:
// config/customErrors.js const ERROR_MESSAGES = { NETWORK_ERROR: "Network error. Please check your connection and try again.", BAD_REQUEST: "There was an issue with your request. Please check and try again.", UNAUTHORIZED: "You are not authorized to perform this action. Please log in.", FORBIDDEN: "Access denied. You don't have permission to view this resource.", NOT_FOUND: "The requested resource was not found.", GENERIC_ERROR: "Something went wrong. Please try again later.", // You can add more messages here if you want }; export default ERROR_MESSAGES;
說明:
使用 Axios 取消令牌,透過在元件卸載時取消正在進行的請求來防止記憶體洩漏。
實作:
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
說明:
實作這些先進技術可以將您的錯誤處理系統提升到一個新的水平:
這些增強功能是可選的,但非常有價值,因為它們為應用程式的錯誤處理方法增加了深度、靈活性和以使用者為中心的改進。
當元件透過useApi啟動API呼叫時,會觸發下列流程:
每個服務模組(例如 userService、productService)都會為特定 API 端點定義函數並使用配置的 axiosInstance。元件僅與這些服務功能互動。
元件將服務函數(例如,productService.getProducts)傳遞給useApi。當 request 被呼叫時,useApi 將函數轉送給服務,然後服務透過 axiosInstance 發出 HTTP 請求。
axiosInstance 中的攔截器處理錯誤日誌記錄、解析預先定義的自訂錯誤訊息並集中錯誤處理。
useApi 將結構化狀態(資料、載入和錯誤)傳回給元件,使其能夠專注於呈現資料和處理互動。
以下概述描述了錯誤處理系統中的每個元件如何在應用程式內交互,從最初的 API 呼叫到使用者回饋:
組件
使用Api Hook
服務模組
Axios 實例
API 回應
錯誤處理與使用者通知
此流程支援集中式錯誤管理和一致的使用者回饋,允許元件僅專注於呈現數據,而不需要處理重複的錯誤檢查邏輯。
此範例示範了從進行 API 呼叫到顯示資料的整個流程,以及集中的錯誤處理和回饋。
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
導入語句:
鉤子初始化:
API 呼叫觸發器:
錯誤處理:
條件渲染:
此範例示範了集中式錯誤處理如何簡化元件邏輯並確保一致的使用者回饋。
遵守最佳實務可確保您的錯誤處理系統高效、可維護且使用者友好。
透過以下資源增強您對本指南中涵蓋的概念的理解:
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
const axiosInstance = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || '', headers: { 'Content-Type': 'application/json', }, });
管理不同的環境可確保您的應用程式在開發、測試和生產過程中與正確的 API 端點互動。
在專案根目錄中建立 .env.local 檔案並定義 API 基本 URL:
axiosInstance.interceptors.response.use( (response) => response, // Pass through successful responses (error) => { if (!error.response) { toast.error(ERROR_MESSAGES.NETWORK_ERROR); return Promise.reject(error); } const { status, data } = error.response; let message = ERROR_MESSAGES[status] || ERROR_MESSAGES.GENERIC_ERROR; // Custom logic for specific error types if (data?.type === 'validation') { message = `Validation Error: ${data.message}`; } else if (data?.type === 'authentication') { message = `Authentication Error: ${data.message}`; } // Display error notification toast.error(message); // Handle unauthorized access by redirecting to login if (status === 401) { Router.push('/login'); } return Promise.reject(error); } );
確保您的 Axios 實例使用環境變數:
// utils/axiosInstance.js import axios from 'axios'; import ERROR_MESSAGES from '../config/customErrors'; import { toast } from 'react-toastify'; import Router from 'next/router';
透過建立集中式錯誤處理系統,您已經建立了一個乾淨、模組化且使用者友好的結構,可以提高開發人員體驗和使用者滿意度。無論您是剛開始還是希望增強應用程式的錯誤管理,此方法都提供了可以與您的應用程式一起成長的堅實基礎。
鼓勵自己嘗試此處描述的功能,從基礎知識開始,並在您熟悉後添加增強功能。集中式錯誤處理方法是一項寶貴的技能和實踐,隨著應用程式的擴展,它會帶來回報。
實施本指南中概述的策略,以體驗更清晰的程式碼、一致的使用者通知和改進的可維護性。
有問題、建議或經驗可以分享嗎?透過發表評論或在 GitHub 和 Twitter 上聯繫來與社群互動。
我正在開發一個基於這個集中式錯誤處理系統的 npm 套件。請繼續關注更新,或推薦您認為有價值的功能!
編碼快樂! ?✨
以上是使用 Axios 和自訂 Hook 建立強大的前端錯誤處理系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!