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

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

- 順序資料獲取:路由中的請求相互依賴,因此會產生瀑布效應。有時您可能需要這種模式,因為一個請求依賴於另一個請求的結果,或者您希望在滿足條件後再進行下一個請求以節省資源。然而,這種行為也可能是無意的,導致載入時間變長。
- 平行資料獲取:路由中的請求會立即啟動並同時載入資料。這減少了客戶端與伺服器之間的瀑布效應以及載入資料的總時間。
順序資料獲取
如果有巢狀元件,且每個元件都獲取自己的資料,那麼如果這些資料請求不同(這不適用於請求相同資料的情況,因為它們會自動記憶化),資料獲取將按順序進行。
例如,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
套件來確保伺服器端資料獲取函數永遠不會在客戶端使用。