文章目錄
- 前言
- 一、核心作用
- 二、工作原理
- 三、使用場景
- 1. 避免重復數據請求
- 2. 優化昂貴計算
- 四、緩存規則詳解
- 五、與其它緩存方式對比
- 六、服務端特殊行為
- 七、最佳實踐
- 八、緩存失效策略
- 九、使用限制
- 十、與數據獲取庫集成
- 總結:何時使用 cache()
前言
React 的 cache()
函數是 React 19 引入的重要 API,主要用于優化重復計算和數據獲取。以下是對 cache()
函數的詳細解析:
一、核心作用
cache()
創建一個緩存版本的函數,當相同參數重復調用時直接返回緩存結果:
import { cache } from 'react';const cachedFn = cache(fn);
二、工作原理
- 首次調用:執行函數并緩存結果
- 相同參數再次調用:直接返回緩存值(不執行函數)
- 不同參數調用:重新執行并緩存新結果
三、使用場景
1. 避免重復數據請求
const getData = cache(async (id) => {const res = await fetch(`https://api.example.com/data/${id}`);return res.json();
});async function Component({ id }) {const data = await getData(id); // 相同id只請求一次
}
2. 優化昂貴計算
const calculateSum = cache((a, b) => {// 復雜計算邏輯return a + b;
});function Component() {const result = calculateSum(5, 10); // 相同參數直接返回緩存
}
四、緩存規則詳解
行為 | 結果 |
---|---|
相同參數調用 | 返回緩存值 |
不同參數調用 | 執行函數并緩存新結果 |
服務端組件間調用 | 同一請求共享緩存 |
客戶端組件間調用 | 整個應用生命周期共享緩存 |
五、與其它緩存方式對比
方法 | 適用場景 | 緩存范圍 | 持久性 |
---|---|---|---|
cache() | 跨組件/服務端-客戶端 | 全局 | 請求/會話級 |
useMemo | 單組件內部 | 組件實例 | 渲染周期 |
useCallback | 事件處理函數 | 組件實例 | 依賴變更前 |
React.memo | 組件渲染結果 | 組件實例 | Props 不變時 |
六、服務端特殊行為
在 RSC(服務器組件)中:
- 緩存自動綁定到當前請求
- 請求結束時緩存自動清除
- 不同請求之間的緩存完全隔離
// 服務端組件
export default async function Page() {const data = await getData(1); // 緩存綁定到該HTTP請求
}
七、最佳實踐
-
純函數優先:只緩存無副作用的函數
// ? 推薦:純函數 const getPrice = cache((productId) => ...)// ? 避免:有副作用函數 const updateDB = cache(() => { ... }) // 危險!
-
客戶端組件使用注意:
'use client'; import { cache } from 'react';// 客戶端需單例模式 const cachedFn = cache(fn); export default function ClientComp() {// 使用cachedFn }
-
避免緩存大型對象:
// ? 不推薦 const getHugeData = cache(() => 1GB數據)// ? 推薦 const getDataChunk = cache((chunkId) => 小塊數據)
八、緩存失效策略
React 未內置失效機制,需手動實現:
// 自定義帶失效時間的緩存
const createTimedCache = (fn, ttl = 60_000) => {const cache = new Map();return (...args) => {const key = JSON.stringify(args);if (cache.has(key)) {const { timestamp, value } = cache.get(key);if (Date.now() - timestamp < ttl) return value;}const value = fn(...args);cache.set(key, { value, timestamp: Date.now() });return value;};
};
九、使用限制
- 參數必須可序列化:對象/數組需結構穩定
- 避免閉包陷阱:
function Component() {// ? 錯誤:每次渲染創建新函數const badCache = cache((x) => ...);// ? 正確:模塊級緩存return <Child /> }// 模塊級緩存 const goodCache = cache((x) => ...);
十、與數據獲取庫集成
配合 Next.js / SWR 等庫:
// Next.js 示例
import { cache } from 'react';export const revalidate = 3600; // 每小時重新驗證const getData = cache(async (id) => {const res = await fetch(`https://...`);return res.json();
});export async function generateStaticParams() {const data = await getData();return data.map(item => ({ id: item.id }));
}
總結:何時使用 cache()
場景 | 推薦使用 |
---|---|
跨組件共享數據獲取邏輯 | ? |
避免重復 API 請求 | ? |
計算密集型操作優化 | ? |
事件處理函數 | ? |
狀態更新邏輯 | ? |
需要即時失效的緩存 | ? (需擴展) |
通過合理使用 cache()
,可顯著提升 React 應用性能,特別在 RSC 架構中能有效減少不必要的計算和網絡請求。