資料獲取、快取與重新驗證
資料獲取是任何應用程式的核心部分。本頁將介紹如何在 React 和 Next.js 中獲取、快取及重新驗證資料。
有四種方式可以獲取資料:
在伺服器端使用 fetch
獲取資料
Next.js 擴展了原生的 fetch
Web API,讓您可以為伺服器端的每個 fetch 請求配置快取和重新驗證行為。React 則擴展了 fetch
,使其在渲染 React 元件樹時自動記憶化 fetch 請求。
您可以在伺服器元件、路由處理器和伺服器動作中使用 async
/await
搭配 fetch
。
例如:
須知事項:
快取資料
快取會儲存資料,因此不需要在每次請求時都從資料來源重新獲取。
預設情況下,Next.js 會自動將 fetch
的返回值快取在伺服器的資料快取中。這意味著資料可以在建置時或請求時獲取、快取,並在每次資料請求時重複使用。
但也有例外情況,fetch
請求在以下情況下不會被快取:
什麼是資料快取?
資料快取是一個持久的 HTTP 快取。根據您的平台,快取可以自動擴展並跨多個區域共享。
了解更多關於資料快取的資訊。
重新驗證資料
重新驗證是清除資料快取並重新獲取最新資料的過程。這在資料變更且您希望確保顯示最新資訊時非常有用。
快取的資料可以通過兩種方式重新驗證:
- 基於時間的重新驗證:在經過一定時間後自動重新驗證資料。這適用於變更不頻繁且即時性不那麼關鍵的資料。
- 按需重新驗證:根據事件(例如表單提交)手動重新驗證資料。按需重新驗證可以使用基於標籤或路徑的方法來一次性重新驗證一組資料。這適用於您希望盡快顯示最新資料的情況(例如當您的無頭 CMS 內容更新時)。
基於時間的重新驗證
要按時間間隔重新驗證資料,您可以使用 fetch
的 next.revalidate
選項來設定資源的快取生命週期(以秒為單位)。
或者,要重新驗證路由段中的所有 fetch
請求,您可以使用路由段配置選項。
如果在靜態渲染的路由中有多個 fetch 請求,且每個請求有不同的重新驗證頻率,則所有請求將使用最短的時間。對於動態渲染的路由,每個 fetch
請求將獨立重新驗證。
了解更多關於基於時間的重新驗證。
按需重新驗證
可以在伺服器動作或路由處理器中通過路徑 (revalidatePath
) 或快取標籤 (revalidateTag
) 按需重新驗證資料。
Next.js 有一個快取標籤系統,用於跨路由使 fetch
請求失效。
- 使用
fetch
時,您可以選擇用一個或多個標籤標記快取條目。 - 然後,您可以呼叫
revalidateTag
來重新驗證與該標籤關聯的所有條目。
例如,以下 fetch
請求添加了快取標籤 collection
:
然後,您可以通過在伺服器動作中呼叫 revalidateTag
來重新驗證標記為 collection
的 fetch
呼叫:
了解更多關於按需重新驗證。
錯誤處理與重新驗證
如果在嘗試重新驗證資料時拋出錯誤,則將繼續從快取中提供最後一次成功生成的資料。在後續請求中,Next.js 將重試重新驗證資料。
選擇退出資料快取
fetch
請求在以下情況下不會被快取:
- 在
fetch
請求中添加了cache: 'no-store'
。 - 在個別
fetch
請求中添加了revalidate: 0
選項。 fetch
請求位於使用POST
方法的路由處理器中。fetch
請求在使用headers
或cookies
之後。- 使用了
const dynamic = 'force-dynamic'
路由段選項。 fetchCache
路由段選項配置為預設跳過快取。fetch
請求使用了Authorization
或Cookie
標頭,並且元件樹中有未快取的請求在其之上。
個別 fetch
請求
要為個別 fetch
請求選擇退出快取,您可以將 fetch
中的 cache
選項設為 'no-store'
。這將在每次請求時動態獲取資料。
查看所有可用的 cache
選項,請參閱 fetch
API 參考。
多個 fetch
請求
如果在路由段(例如佈局或頁面)中有多個 fetch
請求,您可以使用路由段配置選項來配置該段中所有資料請求的快取行為。
不過,我們建議為每個 fetch
請求單獨配置快取行為。這樣可以更精細地控制快取行為。
在伺服器端使用第三方函式庫獲取資料
在使用不支援或未公開 fetch
的第三方函式庫(例如資料庫、CMS 或 ORM 客戶端)時,您可以使用路由段配置選項和 React 的 cache
函式來配置這些請求的快取和重新驗證行為。
資料是否被快取取決於路由段是靜態或動態渲染。如果路由段是靜態的(預設值),則請求的輸出將作為路由段的一部分被快取和重新驗證。如果路由段是動態的,則請求的輸出將不會被快取,並會在每次渲染該段時重新獲取。
您還可以使用實驗性的 unstable_cache
API。
範例
在以下範例中:
- React 的
cache
函式用於記憶化資料請求。 - 在佈局和頁面段中將
revalidate
選項設為3600
,意味著資料將被快取並最多每小時重新驗證一次。
儘管 getItem
函式被呼叫了兩次,但只會向資料庫發送一個查詢。
在客戶端使用路由處理器獲取資料
如果需要在客戶端元件中獲取資料,您可以從客戶端呼叫路由處理器。路由處理器在伺服器上執行並將資料返回給客戶端。這在您不想向客戶端暴露敏感資訊(例如 API 令牌)時非常有用。
請參閱路由處理器文件以獲取範例。
伺服器元件與路由處理器
由於伺服器元件在伺服器上渲染,因此您不需要從伺服器元件呼叫路由處理器來獲取資料。相反,您可以直接在伺服器元件中獲取資料。
在客戶端使用第三方函式庫獲取資料
您也可以使用第三方函式庫(例如 SWR 或 TanStack Query)在客戶端獲取資料。這些函式庫提供了自己的 API 來記憶化請求、快取、重新驗證和變更資料。
未來的 API:
use
是一個 React 函式,接受並處理由函式返回的 promise。目前在客戶端元件中不建議將fetch
包裝在use
中,這可能會觸發多次重新渲染。了解更多關於use
的資訊,請參閱 React 文件。