模式與最佳實踐
在 React 和 Next.js 中,有幾種推薦的資料獲取模式和最佳實踐。本頁將介紹一些最常見的模式及其使用方法。
在伺服器端獲取資料
只要可能,我們建議使用伺服器元件 (Server Components) 在伺服器端獲取資料。這讓您可以:
- 直接存取後端資料資源(例如資料庫)。
- 防止敏感資訊(如存取令牌和 API 金鑰)暴露給客戶端,從而提高應用程式的安全性。
- 在同一個環境中獲取資料並渲染,減少客戶端與伺服器之間的來回通訊,同時也減少客戶端主執行緒的工作量。
- 通過單次往返執行多次資料獲取,而不是在客戶端發送多個獨立請求。
- 減少客戶端-伺服器的瀑布式請求。
- 根據您所在的區域,資料獲取可以更靠近資料源,從而減少延遲並提高效能。
之後,您可以使用伺服器操作 (Server Actions) 來變更或更新資料。
在需要的地方獲取資料
如果您需要在樹狀結構中的多個元件中使用相同的資料(例如當前使用者),您不必全域獲取資料,也不需要在元件之間傳遞 props。相反,您可以在需要資料的元件中使用 fetch
或 React 的 cache
,而無需擔心多次請求相同資料對效能的影響。
這是因為 fetch
請求會自動被記憶化。了解更多關於請求記憶化的資訊。
小提示:這也適用於佈局 (layouts),因為無法在父佈局和其子元件之間傳遞資料。
串流 (Streaming)
串流和 Suspense 是 React 的功能,允許您逐步渲染並增量串流 UI 單元到客戶端。
透過伺服器元件和嵌套佈局,您可以立即渲染不需要特定資料的頁面部分,並為正在獲取資料的部分顯示載入狀態。這意味著使用者無需等待整個頁面載入完畢即可開始與其互動。

要了解更多關於串流和 Suspense 的資訊,請參閱載入 UI 和串流與 Suspense 頁面。
並行與順序資料獲取
在 React 元件中獲取資料時,需要注意兩種資料獲取模式:並行 (Parallel) 和順序 (Sequential)。

- 順序資料獲取:路由中的請求相互依賴,因此會產生瀑布式請求。在某些情況下,您可能需要這種模式,因為一個請求依賴於另一個請求的結果,或者您希望在滿足某個條件後再進行下一個請求以節省資源。然而,這種行為也可能是無意的,導致載入時間變長。
- 並行資料獲取:路由中的請求會立即啟動,並同時載入資料。這減少了客戶端-伺服器的瀑布式請求以及載入資料的總時間。
順序資料獲取
如果您有嵌套元件,且每個元件都獲取自己的資料,那麼當這些資料請求不同時(這不適用於相同資料的請求,因為它們會自動記憶化),資料獲取將按順序進行。
例如,Playlists
元件只有在 Artist
元件完成資料獲取後才會開始獲取資料,因為 Playlists
依賴於 artistID
prop:
在這種情況下,您可以使用 loading.js
(用於路由段)或 React <Suspense>
(用於嵌套元件)來顯示即時載入狀態,同時 React 會串流傳入結果。
這將防止整個路由被資料獲取阻塞,使用者可以與頁面中未被阻塞的部分互動。
阻塞式資料請求:
防止瀑布式請求的另一種方法是在應用程式的根目錄全域獲取資料,但這會阻塞其下方所有路由段的渲染,直到資料載入完成。這可以描述為「全有或全無」的資料獲取方式。要麼您擁有整個頁面或應用程式的資料,要麼什麼都沒有。
任何使用
await
的請求都會阻塞其下方整個樹狀結構的渲染和資料獲取,除非它們被包裹在<Suspense>
邊界中或使用了loading.js
。另一種選擇是使用並行資料獲取或預載入模式。
並行資料獲取
要並行獲取資料,您可以在使用資料的元件外部定義請求,然後在元件內部呼叫它們。這樣可以通過同時啟動兩個請求來節省時間,但使用者只有在兩個 Promise 都解析後才能看到渲染結果。
在下面的範例中,getArtist
和 getArtistAlbums
函數在 Page
元件外部定義,然後在元件內部呼叫,我們等待兩個 Promise 解析:
為了提升使用者體驗,您可以添加 Suspense 邊界來分割渲染工作,並盡快顯示部分結果。
預載入資料
防止瀑布式請求的另一種方法是使用預載入模式。您可以選擇性地建立一個 preload
函數來進一步優化並行資料獲取。透過這種方法,您無需將 Promise 作為 props 傳遞。preload
函數也可以有任何名稱,因為它是一種模式,而不是 API。
使用 React cache
、server-only
和預載入模式
您可以結合 cache
函數、預載入模式和 server-only
套件來建立一個可以在整個應用程式中使用的資料獲取工具。
透過這種方法,您可以提前獲取資料、快取回應,並確保這些資料獲取僅在伺服器端進行。
utils/get-item
的匯出可以被佈局、頁面或其他元件使用,從而讓它們控制何時獲取項目的資料。
小提示:
- 我們建議使用
server-only
套件 來確保伺服器端資料獲取函數永遠不會在客戶端使用。
防止敏感資料暴露給客戶端
我們建議使用 React 的污染 API taintObjectReference
和 taintUniqueValue
,以防止整個物件實例或敏感值被傳遞給客戶端。
要在您的應用程式中啟用污染功能,請將 Next.js 配置中的 experimental.taint
選項設為 true
:
然後將您想要污染的物件或值傳遞給 experimental_taintObjectReference
或 experimental_taintUniqueValue
函數:
了解更多關於安全性與伺服器操作的資訊。