文章目录
前言
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 架构中能有效减少不必要的计算和网络请求。