在 Web 開發中,CRUD 操作是基本構建塊,對於管理資料至關重要。它們幾乎在每個應用程式中無處不在,從簡單的網站到複雜的企業解決方案。
NestJS Boilerplate 使用者已經能夠評估和使用強大的新工具 - CLI,它允許您自動建立資源及其屬性。使用此工具,您可以進行所有 CRUD 操作並向其中添加必要的字段,而無需手動編寫一行程式碼。同時,正如我們一再宣布的,BC Boilerplates 生態系統包括一個完全相容的 Extective-React-Boilerplate,以提供完整的功能(原則上,它可以是一個完全獨立的解決方案)。現在讓我們從前端角度探討 CRUD 操作。
在具有伺服器端渲染功能的 React 框架 Next.js 中,可以透過增強效能、SEO 和開發人員體驗的功能來有效管理這些操作。之前,我們發表了一篇關於啟動 NextJS 專案的有效方法的文章,現在我們想進一步分析使用 Next.js 中的 API 的細節和細微差別。
眾所周知,CRUD 縮寫代表建立、讀取、更新和刪除。這個概念代表了可以對任何資料執行的基本操作。讓我們考慮使用管理面板使用者的範例來處理 CRUD 操作,其中實現了新增、編輯和刪除使用者等功能,以及檢索有關使用者的信息。下面討論的自訂 React 鉤子,用於處理 React Query 中的資料處理、分頁、錯誤管理等,已經整合到 Extective-React-Boilerplate 中。當然,您可以直接利用這個樣板。在以下部分中,我們將分享我們對實現這些功能的見解。
使用案例:提交資料以建立新資源(例如,使用者註冊、新增產品)。
實作: 從表單收集數據,向伺服器發送 POST 請求,處理回應,並相應地更新 UI。
讓我們觀察一個例子。向 API 發出 POST 請求會合併建立新使用者。在下面的程式碼片段中,usePostUserService 鉤子用於封裝此邏輯。我們已經透過定義請求和回應類型來指定建立新使用者的資料結構,但這裡省略這一部分以幫助您集中註意力。您可以在儲存庫 Extective-React-Boilerplate 中查看更詳細的資訊或更完整的圖片,因為此程式碼片段以及以下所有程式碼片段都來自那裡。
因此,我們將建立一個自訂掛鉤 usePostUserService,它使用 useFetch 掛鉤發送 POST 請求。它將用戶資料作為輸入並將其發送到 API:
function usePostUserService() { const fetch = useFetch(); return useCallback( (data: UserPostRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users`, { method: "POST", body: JSON.stringify(data), ...requestConfig, }).then(wrapperFetchJsonResponse<UserPostResponse>); }, [fetch] ); }
函數wrapperFetchJsonResponse 將在本文稍後討論「錯誤處理」時進行研究。
使用案例:取得並顯示資源清單或單一資源(例如,取得使用者設定檔和產品清單)。
實作:發送 GET 請求來取得數據,處理載入和錯誤狀態,並在 UI 中呈現數據。
在我們的範例中,讀取資料涉及向 API 發出 GET 請求以取得使用者資料。它可以包括使用分頁、過濾器來取得所有用戶,以及在定義請求 (UsersRequest) 和回應類型 (UsersResponse) 後按 ID 排序或取得單一用戶。
要在自訂 useGetUsersService 掛鉤中取得所有使用者,我們發送帶有用於分頁、過濾器和排序的查詢參數的 GET 請求:
function useGetUsersService() { const fetch = useFetch(); return useCallback( (data: UsersRequest, requestConfig?: RequestConfigType) => { const requestUrl = new URL(`${API_URL}/v1/users`); requestUrl.searchParams.append("page", data.page.toString()); requestUrl.searchParams.append("limit", data.limit.toString()); if (data.filters) { requestUrl.searchParams.append("filters", JSON.stringify(data.filters)); } if (data.sort) { requestUrl.searchParams.append("sort", JSON.stringify(data.sort)); } return fetch(requestUrl, { method: "GET", ...requestConfig, }).then(wrapperFetchJsonResponse<UsersResponse>); }, [fetch] ); }
用於取得單一使用者 useGetUserService 掛鉤發送 GET 請求以按 ID 取得使用者:
function useGetUserService() { const fetch = useFetch(); return useCallback( (data: UserRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users/${data.id}`, { method: "GET", ...requestConfig, }).then(wrapperFetchJsonResponse<UserResponse>); }, [fetch] ); }
使用案例:編輯現有資源(例如,更新使用者資訊、編輯部落格文章)。
實作:收集更新的數據,向伺服器發送 PUT 或 PATCH 請求,處理回應,並更新 UI。
讓我們更新現有用戶,這涉及使用更新的用戶資料向 API 發送 PATCH 請求。為此,在自訂 usePatchUserService 掛鉤中,我們在定義請求 UserPatchRequest 和回應類型 UserPatchResponse 後發送帶有使用者 ID 和更新資料的 PATCH 請求:
function usePatchUserService() { const fetch = useFetch(); return useCallback( (data: UserPatchRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users/${data.id}`, { method: "PATCH", body: JSON.stringify(data.data), ...requestConfig, }).then(wrapperFetchJsonResponse<UserPatchResponse>); }, [fetch] ); }
注意:對於部分資料更新,使用 PATCH 取代 PUT 更為高級,而 PUT 通常用於完整資源更新。
使用案例:刪除資源(例如,刪除使用者或從清單中刪除項目)。
實作: 向伺服器發送 DELETE 請求,處理回應,並更新 UI 以反映刪除。
在我們的下一個範例中,刪除使用者涉及使用使用者 ID 向您的 API 發送 DELETE 請求。在 useDeleteUsersService 掛鉤中定義請求 (UsersDeleteRequest) 和回應類型 (UsersDeleteResponse) 後,將傳送 DELETE 請求以透過 ID 刪除使用者。
function usePostUserService() { const fetch = useFetch(); return useCallback( (data: UserPostRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users`, { method: "POST", body: JSON.stringify(data), ...requestConfig, }).then(wrapperFetchJsonResponse<UserPostResponse>); }, [fetch] ); }
這些鉤子抽象化了發出 HTTP 請求和處理回應的複雜性,使用此方法可確保乾淨且可維護的程式碼庫,因為資料擷取邏輯已封裝並可在元件之間重複使用。
好了,我們已經介紹了處理CRUD操作的例子,下面我們來仔細看看Next.js提供的獲取資料的方法,因為它作為一個框架,在React的基礎上增加了它的功能和優化。很明顯,Next.js 除了CSR(客戶端渲染)之外,還提供了高級功能,如SSR(伺服器端渲染)、SSG(靜態站點生成)、內建API 路由和混合渲染。那麼,讓我們討論一下 Next.js 和 React 中檢索資料的共通點和差異。
只要 React 應用程式是純粹的客戶端,那麼資料獲取就會在初始頁面載入後發生在客戶端上。對於每次載入頁面時都需要取得資料的動態頁面,更適合使用SSR,在這種情況下,資料是在請求時在伺服器上取得的。
對於 SSG,它適用於資料不經常更改的靜態頁面,資料是在建置時取得的。因此,getStaticProps 方法可以幫助我們
在建置時取得資料 (SSG)。如果我們需要基於動態路由和建置時取得的資料來預先渲染頁面,則 getStaticPaths 方法允許執行此操作。它與 getStaticProps 結合使用在建置時產生動態路由。需要注意的是,從 Next 14 開始,我們可以直接在元件中發出請求,而無需這些方法,從而提供了更多「React 體驗」。
為了總結有關上述方法的信息,我們可以看一下表格,該表格全面概述了 Next.js 中的不同數據獲取方法,突出顯示了它們各自的時間和用例。
Method | Data Fetching | Timing | Use Case |
---|---|---|---|
getStaticPaths | Static Site Generation (SSG) | At build time | Pre-render pages for dynamic routes based on data available at build time. |
getStaticProps | Static Site Generation (SSG) | At build time | Pre-render pages with static content at build time. Ideal for content that doesn't change frequently. |
getServerSideProps | Server-Side Rendering (SSR) | On each request | Fetch data on the server for each request, providing up-to-date content. Ideal for dynamic content that changes frequently. |
useQuery | Client-Side Rendering (CSR) | After the initial page load | Fetch initial data server-side, hydrate, reduce redundant network requests, Background Refetching. |
useSWR | Client-Side Rendering (CSR) | After the initial page load | Fetch and revalidate data on the client-side, suitable for frequently changing data. |
React Query 提供了用於獲取、快取、同步和更新伺服器狀態的鉤子,使其成為處理 React 和 Next.js 應用程式中資料的絕佳工具。使用它的主要好處是:
QueryClientProvider 是一個上下文提供者元件,它向 React 元件樹提供 QueryClient 實例。這個實例對於使用像 useQuery 這樣的鉤子是必需的。 要進行設置,需要將其放置在組件樹的根部,並為查詢和突變配置全域設置,例如重試行為、快取時間等。之後,它會初始化 React Query 客戶端並使其在整個應用程式中可用。
function usePostUserService() { const fetch = useFetch(); return useCallback( (data: UserPostRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users`, { method: "POST", body: JSON.stringify(data), ...requestConfig, }).then(wrapperFetchJsonResponse<UserPostResponse>); }, [fetch] ); }
那麼,為什麼要把它加到專案中呢?它有益於:
React Query 提供的另一個重要功能是 React Query Devtools - 一個用於檢查和偵錯 React Query 狀態的開發工具。它可以輕鬆添加到您的應用程式中,並透過瀏覽器擴充功能或作為元件進行訪問,如前面的範例所示。
在開發過程中,React Query Devtools 可用於檢查單一查詢和突變,了解為什麼某些查詢會預取並監視查詢快取的狀態,並查看它如何隨著時間的推移而演變。
要使用庫中的功能實現分頁控製或無限滾動,useInfiniteQuery 是完美的選擇。首先,我們產生唯一的鍵,用於在 React Query 中快取和檢索查詢。這裡的 by 方法根據排序和過濾選項創建唯一鍵。
function usePostUserService() { const fetch = useFetch(); return useCallback( (data: UserPostRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users`, { method: "POST", body: JSON.stringify(data), ...requestConfig, }).then(wrapperFetchJsonResponse<UserPostResponse>); }, [fetch] ); }
為此,我們將使用 React Query 中的 useInfiniteQuery 函數,並採用上面讀取操作部分中討論的 useGetUsersService 掛鉤。
function useGetUsersService() { const fetch = useFetch(); return useCallback( (data: UsersRequest, requestConfig?: RequestConfigType) => { const requestUrl = new URL(`${API_URL}/v1/users`); requestUrl.searchParams.append("page", data.page.toString()); requestUrl.searchParams.append("limit", data.limit.toString()); if (data.filters) { requestUrl.searchParams.append("filters", JSON.stringify(data.filters)); } if (data.sort) { requestUrl.searchParams.append("sort", JSON.stringify(data.sort)); } return fetch(requestUrl, { method: "GET", ...requestConfig, }).then(wrapperFetchJsonResponse<UsersResponse>); }, [fetch] ); }
這裡的 QueryFn 根據當前頁面、過濾器和排序參數檢索用戶數據,而 getNextPageParam 函數根據上一頁的響應確定要獲取的下一頁。當使用者滾動或請求更多資料時,useInfiniteQuery 會根據 nextPage 參數自動檢索下一組資料 - 這就是無限滾動發生的方式。查詢的快取時間由 gcTime 參數設定。
總的來說,React Query 提供了一個用於管理和偵錯 React 應用程式中伺服器狀態的全面解決方案。 QueryClientProvider 確保所有查詢和突變的集中且一致的配置,而 ReactQueryDevtools 提供強大的工具用於在開發過程中檢查和理解查詢行為。
實現 CRUD 操作始終需要適當的錯誤處理,以確保使用者友善性和應用程式可靠性。伺服器錯誤通常與客戶端請求處理失敗、伺服器程式碼錯誤、資源過載、基礎架構設定錯誤或外部服務故障有關。對於錯誤處理,Extective-react-boilerplate 建議使用wrapperFetchJsonResponse 函數:
function useGetUserService() { const fetch = useFetch(); return useCallback( (data: UserRequest, requestConfig?: RequestConfigType) => { return fetch(`${API_URL}/v1/users/${data.id}`, { method: "GET", ...requestConfig, }).then(wrapperFetchJsonResponse<UserResponse>); }, [fetch] ); }
在本文中,我們介紹了基本的 CRUD 操作,探索了 NextJS 中的資料檢索技術。我們深入研究了使用 React Query 來管理狀態,也概述了 QueryClientProvider 和 ReactQueryDevtools 用於偵錯和最佳化資料檢索的功能。此外,我們還討論瞭如何實現分頁和無限滾動來處理大型資料集,並解決了錯誤處理問題,使您的應用程式更具彈性並確保流暢的使用者體驗。
透過遵循本文中概述的範例和技術,您現在應該能夠在 NextJS 專案中處理 CRUD 操作。或者,您可以為您的專案使用我們的 Extective-react-boilerplate 範本。它具有完全相容的 Nestjs-boilerplate 後端,可以在幾分鐘內實現使用 CRUD 操作的能力,而無需使用 CLI 編寫一行程式碼,我們已在此處和此處針對實體關係更詳細地介紹了這一點。不斷嘗試,隨時了解最佳實踐,如果您發現它有用,歡迎嘗試此樣板。
我們的 BC Boilerplates 團隊始終在尋找加強開發的方法。我們很想聽聽您對 GitHub 討論或下面評論的想法。
本文全部歸功於 Olena Vlasenko 和 Vlad Shchepotin ??
以上是使用 NextJS 掌握 CRUD的詳細內容。更多資訊請關注PHP中文網其他相關文章!