如何獲取資料並進行串流
本頁將引導您了解如何在伺服器和客戶端元件中獲取資料,以及如何串流依賴於資料的元件。
獲取資料
伺服器元件
您可以在伺服器元件中使用以下方式獲取資料:
使用 fetch
API
要使用 fetch
API 獲取資料,請將您的元件轉換為非同步函數,並等待 fetch
呼叫。例如:
須知:
fetch
回應預設不會被快取。然而,Next.js 會預渲染路由,並且輸出會被快取以提升效能。如果您想選擇動態渲染,請使用{ cache: 'no-store' }
選項。請參閱fetch
API 參考。- 在開發過程中,您可以記錄
fetch
呼叫以便更好地進行可見性和除錯。請參閱logging
API 參考。
使用 ORM 或資料庫
由於伺服器元件是在伺服器上渲染的,您可以安全地使用 ORM 或資料庫客戶端進行資料庫查詢。將您的元件轉換為非同步函數,並等待呼叫:
客戶端元件
在客戶端元件中有兩種方式可以獲取資料:
- 使用 React 的
use
hook - 使用社群函式庫如 SWR 或 React Query
使用 use
hook 串流資料
您可以使用 React 的 use
hook 從伺服器串流資料到客戶端。首先在伺服器元件中獲取資料,然後將 promise 作為 prop 傳遞給您的客戶端元件:
然後,在您的客戶端元件中,使用 use
hook 來讀取 promise:
在上面的範例中,<Posts>
元件被包裹在 <Suspense>
邊界中。這意味著在 promise 被解析時會顯示 fallback。了解更多關於串流的資訊。
社群函式庫
您可以使用社群函式庫如 SWR 或 React Query 在客戶端元件中獲取資料。這些函式庫有自己關於快取、串流和其他功能的語意。例如,使用 SWR:
使用 React.cache
去重複請求
去重複是防止在渲染過程中對同一資源進行重複請求的過程。它允許您在不同的元件中獲取相同的資料,同時防止對資料來源進行多次網路請求。
如果您使用 fetch
,可以通過添加 cache: 'force-cache'
來去重複請求。這意味著您可以安全地使用相同的 URL 和選項呼叫,並且只會發出一個請求。
如果您不使用 fetch
,而是直接使用 ORM 或資料庫,則可以使用 React cache
函數來包裹您的資料獲取。
串流
警告: 以下內容假設您的應用程式中啟用了
dynamicIO
配置選項。該標誌在 Next.js 15 canary 中引入。
在伺服器元件中使用 async/await
時,Next.js 會選擇動態渲染。這意味著資料將在伺服器上為每個使用者請求進行獲取和渲染。如果有任何慢速資料請求,整個路由將被阻止渲染。
為了改善初始載入時間和使用者體驗,您可以使用串流將頁面的 HTML 分成較小的塊,並逐步將這些塊從伺服器發送到客戶端。

有兩種方式可以在您的應用程式中實現串流:
- 使用
loading.js
檔案包裹頁面 - 使用
<Suspense>
包裹元件
使用 loading.js
您可以在與您的頁面相同的資料夾中創建一個 loading.js
檔案,以在資料獲取時串流整個頁面。例如,要串流 app/blog/page.js
,請在 app/blog
資料夾中添加該檔案。

在導航時,使用者將立即看到佈局和載入狀態,同時頁面正在渲染。一旦渲染完成,新內容將自動替換。

在後台,loading.js
將被嵌套在 layout.js
中,並自動將 page.js
檔案及其下方的任何子元件包裹在 <Suspense>
邊界中。

這種方法適用於路由段(佈局和頁面),但對於更細粒度的串流,您可以使用 <Suspense>
。
使用 <Suspense>
<Suspense>
允許您更細粒度地控制頁面的哪些部分要串流。例如,您可以立即顯示 <Suspense>
邊界之外的任何頁面內容,並在邊界內串流部落格文章列表。
創建有意義的載入狀態
即時載入狀態是在導航後立即向使用者顯示的 fallback UI。為了獲得最佳使用者體驗,我們建議設計有意義的載入狀態,幫助使用者理解應用程式正在響應。例如,您可以使用骨架和旋轉器,或未來螢幕的一小部分但有意義的部分,如封面照片、標題等。
在開發過程中,您可以使用 React Devtools 預覽和檢查元件的載入狀態。
範例
順序資料獲取
順序資料獲取發生在樹中的嵌套元件各自獲取其自己的資料且請求未被去重複時,導致更長的回應時間。

有時您可能希望使用這種模式,因為一個獲取依賴於另一個的結果。
例如,<Playlists>
元件只有在 <Artist>
元件完成獲取資料後才會開始獲取資料,因為 <Playlists>
依賴於 artistID
prop:
為了改善使用者體驗,您應該使用 React <Suspense>
來顯示 fallback
當資料正在獲取時。這將啟用串流並防止整個路由被順序資料請求阻塞。
平行資料獲取 (Parallel data fetching)
當路由中的資料請求被積極初始化並同時開始時,就會發生平行資料獲取。
預設情況下,版面配置 (layouts) 和頁面 (pages) 是平行渲染的。因此每個區段 (segment) 都會盡快開始獲取資料。
然而,在_任何_元件中,多個 async
/await
請求如果彼此前後放置,仍然可能是順序執行的。例如,getAlbums
將會被阻塞,直到 getArtist
解析完成:
您可以透過將請求定義在使用資料的元件之外,並一起解析它們來平行初始化請求,例如使用 Promise.all
:
小知識: 當使用
Promise.all
時,如果一個請求失敗,整個操作都會失敗。要處理這種情況,可以使用Promise.allSettled
方法替代。
預載資料 (Preloading data)
您可以透過建立一個工具函數來預載資料,並在阻塞請求之前積極呼叫它。<Item>
會根據 checkIsAvailable()
函數的結果條件式渲染。
您可以在 checkIsAvailable()
之前呼叫 preload()
來積極初始化 <Item/>
的資料依賴。當 <Item/>
渲染時,其資料已經被獲取完成。
此外,您可以使用 React 的 cache
函數 和 server-only
套件 來建立可重複使用的工具函數。這種方法可以快取資料獲取函數,並確保它只在伺服器端執行。