React 的 `cache()` 函数

发布于:2025-07-22 ⋅ 阅读:(18) ⋅ 点赞:(0)


前言

React 的 cache() 函数是 React 19 引入的重要 API,主要用于优化重复计算和数据获取。以下是对 cache() 函数的详细解析:


一、核心作用

cache() 创建一个缓存版本的函数,当相同参数重复调用时直接返回缓存结果:

import { cache } from 'react';

const cachedFn = cache(fn);

二、工作原理

  1. 首次调用:执行函数并缓存结果
  2. 相同参数再次调用:直接返回缓存值(不执行函数)
  3. 不同参数调用:重新执行并缓存新结果

三、使用场景

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(服务器组件)中:

  1. 缓存自动绑定到当前请求
  2. 请求结束时缓存自动清除
  3. 不同请求之间的缓存完全隔离
// 服务端组件
export default async function Page() {
  const data = await getData(1); // 缓存绑定到该HTTP请求
}

七、最佳实践

  1. 纯函数优先:只缓存无副作用的函数

    // ✅ 推荐:纯函数
    const getPrice = cache((productId) => ...)
    
    // ❌ 避免:有副作用函数
    const updateDB = cache(() => { ... }) // 危险!
    
  2. 客户端组件使用注意

    'use client';
    import { cache } from 'react';
    
    // 客户端需单例模式
    const cachedFn = cache(fn);
    export default function ClientComp() {
      // 使用cachedFn
    }
    
  3. 避免缓存大型对象

    // ❌ 不推荐
    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;
  };
};

九、使用限制

  1. 参数必须可序列化:对象/数组需结构稳定
  2. 避免闭包陷阱
    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 架构中能有效减少不必要的计算和网络请求。


网站公告

今日签到

点亮在社区的每一天
去签到