unstable_cache 与 React cache()
使用 Next.js 缓存工具按请求或跨请求缓存耗时的函数结果。
unstable_cache 与 React cache() 是 CoddyKit 上的免费 React Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
两个缓存工具
Next.js 提供两个互补的缓存工具:unstable_cache 用于跨请求的持久缓存,React 的 cache() 用于每个请求内的去重。
React cache() — 每个请求内去重
React 提供的 cache(fn) 会在单次服务器渲染过程中记忆函数结果。两个服务器组件调用同一个缓存函数时,会获得相同的结果,而无需再次调用数据库或 API。
import { cache } from 'react';
export const getUser = cache(async (id: string) => {
return db.user.findUnique({ where: { id } });
});
// Both components call getUser(id) — only one DB query fires per request
// component A: const user = await getUser('1');
// component B: const user = await getUser('1'); // uses cached resultunstable_cache — 持久化缓存
unstable_cache(fn, keyParts, options) 会持久化保存结果,使其在多次请求之间保持有效,直到显式重新验证。您可以把它理解为适用于任意异步函数(数据库查询、Redis 调用等)的 fetch({ next: { revalidate } })。
import { unstable_cache } from 'next/cache';
const getProducts = unstable_cache(
async () => db.products.findMany(),
['products-list'], // cache key parts
{ revalidate: 60, tags: ['products'] } // options
);
// In a Server Component:
const products = await getProducts();缓存键组成部分
unstable_cache 的第二个参数是一个字符串数组,用于组成缓存键。请包含所有会影响输出的变量。
const getUserPosts = unstable_cache(
async (userId: string) => db.posts.findMany({ where: { userId } }),
['user-posts'], // base key
{ tags: [`user-${userId}-posts`] } // per-user tag
);
// Call with userId — Next.js appends the argument to the key:
const posts = await getUserPosts(userId);按需重新验证的标签
为缓存函数添加标签,并在数据发生变化时使用 revalidateTag() 使其失效,例如在服务器操作中执行数据变更后。
// Server Action
async function createProduct(data: FormData) {
'use server';
await db.products.create({ data: parseFormData(data) });
revalidateTag('products'); // invalidates all cached functions tagged 'products'
redirect('/products');
}基于时间的重新验证
在选项中设置 revalidate: N,即可在 N 秒后重新验证缓存,其原理类似于 fetch 调用中的 ISR。
const getStats = unstable_cache(
async () => computeHeavyStats(),
['dashboard-stats'],
{ revalidate: 300 } // recompute at most every 5 minutes
);组合使用 cache() 和 unstable_cache
对于在一次渲染中从多个位置调用的函数,请在 unstable_cache 内使用 cache():既能在一次请求中去重,又能在多次请求之间持久化结果。
// Deduplicate the DB call within a request:
export const getRawUser = cache(async (id: string) => db.user.findUnique({ where: { id } }));
// And cache the result persistently:
export const getUser = unstable_cache(getRawUser, ['user'], { revalidate: 60, tags: ['user'] });unstable_cache 的限制
unstable_cache 被标记为不稳定,是因为其 API 在正式稳定前可能发生变化。缓存函数无法访问 Cookie 或请求标头等特定于请求的数据。
用于布局数据的 React cache()
使用 cache() 包装布局级别的数据获取函数,这样布局和调用同一函数的嵌套页面就能在一次渲染中共享结果。
// lib/data.ts
export const getCurrentUser = cache(async () => {
const session = await getServerSession();
return db.user.findUnique({ where: { id: session?.userId } });
});
// layout.tsx and page.tsx both call getCurrentUser() — one DB query如何选择
cache():在一次渲染中去重相同的调用(同一请求)。unstable_cache:在多次请求之间持久化结果,直到重新验证。调用外部 HTTP API 时,请使用 fetch 和 next.revalidate。
快速检查
React 的 cache() 与 Next.js 的 unstable_cache 之间的关键区别是什么?
回顾
cache(fn) 会在一次渲染过程中去重调用,非常适合共享布局数据和页面数据。unstable_cache(fn, keys, { revalidate, tags }) 会在多次请求之间持久化结果,并支持基于时间或标签的失效,非常适合开销较大的数据库查询。
常见问题解答
「unstable_cache 与 React cache()」课时是免费的吗?
是的 — 「unstable_cache 与 React cache()」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「unstable_cache 与 React cache()」这节课中我会学到什么?
使用 Next.js 缓存工具按请求或跨请求缓存耗时的函数结果。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「unstable_cache 与 React cache()」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Next.js 中带缓存选项的 fetch()
- unstable_cache 与 React cache()
- 增量静态再生成(ISR)
- 用于数据变更的服务器操作