React 的 `cache()` 函数
文章目录
- 前言
- 一、核心作用
- 二、工作原理
- 三、使用场景
- 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 架构中能有效减少不必要的计算和网络请求。