Skip to main content Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/midudev/preguntas-entrevista-react --skill next-cache-components命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... name next-cache-components description Next.js 16 Cache Components - PPR, use cache directive, cacheLife, cacheTag, updateTag
Cache Components (Next.js 16+)
Cache Components enable Partial Prerendering (PPR) - mix static, cached, and dynamic content in a single route.
Enable Cache Components
import type { NextConfig } from 'next'
const nextConfig : NextConfig = {
cacheComponents : true ,
}
export default nextConfig
This replaces the old experimental.ppr flag.
Three Content Types
With Cache Components enabled, content falls into three categories:
1. Static (Auto-Prerendered)
Synchronous code, imports, pure computations - prerendered at build time:
export default function Page ( ) {
return (
<header >
<h1 > Our Blog</h1 > {/* Static - instant */}
< > ...
)
}
nav
</nav >
</header >
2. Cached (use cache) Async data that doesn't need fresh fetches every request:
async function BlogPosts ( ) {
'use cache'
cacheLife ('hours' )
const posts = await db.posts .findMany ()
return <PostList posts ={posts} />
}
3. Dynamic (Suspense) Runtime data that must be fresh - wrap in Suspense:
import { Suspense } from 'react'
export default function Page ( ) {
return (
<>
<BlogPosts /> {/* Cached */}
<Suspense fallback ={ <p > Loading...</p > }>
<UserPreferences /> {/* Dynamic - streams in */}
</Suspense >
</>
)
}
async function UserPreferences ( ) {
const theme = (await cookies ()).get ('theme' )?.value
return <p > Theme: {theme}</p >
}
use cache Directive
File Level 'use cache'
export default async function Page ( ) {
const data = await fetchData ()
return <div > {data}</div >
}
Component Level export async function CachedComponent ( ) {
'use cache'
const data = await fetchData ()
return <div > {data}</div >
}
Function Level export async function getData ( ) {
'use cache'
return db.query ('SELECT * FROM posts' )
}
Cache Profiles
Built-in Profiles
cacheLife() - Custom Lifetimeimport { cacheLife } from 'next/cache'
async function getData ( ) {
'use cache'
cacheLife ('hours' )
return fetch ('/api/data' )
}
Built-in profiles: 'default', 'minutes', 'hours', 'days', 'weeks', 'max'
Inline Configuration async function getData ( ) {
'use cache'
cacheLife ({
stale : 3600 ,
revalidate : 7200 ,
expire : 86400 ,
})
return fetch ('/api/data' )
}
Cache Invalidation
cacheTag() - Tag Cached Contentimport { cacheTag } from 'next/cache'
async function getProducts ( ) {
'use cache'
cacheTag ('products' )
return db.products .findMany ()
}
async function getProduct (id : string ) {
'use cache'
cacheTag ('products' , `product-${id} ` )
return db.products .findUnique ({ where : { id } })
}
updateTag() - Immediate InvalidationUse when you need the cache refreshed within the same request:
'use server'
import { updateTag } from 'next/cache'
export async function updateProduct (id : string , data : FormData ) {
await db.products .update ({ where : { id }, data })
updateTag (`product-${id} ` )
}
revalidateTag() - Background RevalidationUse for stale-while-revalidate behavior:
'use server'
import { revalidateTag } from 'next/cache'
export async function createPost (data : FormData ) {
await db.posts .create ({ data })
revalidateTag ('posts' )
}
Runtime Data Constraint Cannot access cookies(), headers(), or searchParams inside use cache.
Solution: Pass as Arguments
async function CachedProfile ( ) {
'use cache'
const session = (await cookies ()).get ('session' )?.value
return <div > {session}</div >
}
async function ProfilePage ( ) {
const session = (await cookies ()).get ('session' )?.value
return <CachedProfile sessionId ={session} />
}
async function CachedProfile ({ sessionId }: { sessionId: string } ) {
'use cache'
const data = await fetchUserData (sessionId)
return <div > {data.name}</div >
}
Exception: use cache: private For compliance requirements when you can't refactor:
async function getData ( ) {
'use cache: private'
const session = (await cookies ()).get ('session' )?.value
return fetchData (session)
}
Cache Key Generation Cache keys are automatic based on:
Build ID - invalidates all caches on deploy
Function ID - hash of function location
Serializable arguments - props become part of key
Closure variables - outer scope values included
async function Component ({ userId }: { userId: string } ) {
const getData = async (filter : string ) => {
'use cache'
return fetch (`/api/users/${userId} ?filter=${filter} ` )
}
return getData ('active' )
}
Complete Example import { Suspense } from 'react'
import { cookies } from 'next/headers'
import { cacheLife, cacheTag } from 'next/cache'
export default function DashboardPage ( ) {
return (
<>
{/* Static shell - instant from CDN */}
<header > <h1 > Dashboard</h1 > </header >
<nav > ...</nav >
{/* Cached - fast, revalidates hourly */}
<Stats />
{/* Dynamic - streams in with fresh data */}
<Suspense fallback ={ <NotificationsSkeleton /> }>
<Notifications />
</Suspense >
</>
)
}
async function Stats ( ) {
'use cache'
cacheLife ('hours' )
cacheTag ('dashboard-stats' )
const stats = await db.stats .aggregate ()
return <StatsDisplay stats ={stats} />
}
async function Notifications ( ) {
const userId = (await cookies ()).get ('userId' )?.value
const notifications = await db.notifications .findMany ({
where : { userId, read : false }
})
return <NotificationList items ={notifications} />
}
Migration from Previous Versions Old Config Replacement experimental.pprcacheComponents: truedynamic = 'force-dynamic'Remove (default behavior) dynamic = 'force-static''use cache' + cacheLife('max')revalidate = NcacheLife({ revalidate: N })unstable_cache()'use cache' directive
Migrating unstable_cache to use cache unstable_cache has been replaced by the use cache directive in Next.js 16. When cacheComponents is enabled, convert unstable_cache calls to use cache functions:
import { unstable_cache } from 'next/cache'
const getCachedUser = unstable_cache (
async (id) => getUser (id),
['my-app-user' ],
{
tags : ['users' ],
revalidate : 60 ,
}
)
export default async function Page ({ params }: { params: Promise <{ id: string }> } ) {
const { id } = await params
const user = await getCachedUser (id)
return <div > {user.name}</div >
}
import { cacheLife, cacheTag } from 'next/cache'
async function getCachedUser (id : string ) {
'use cache'
cacheTag ('users' )
cacheLife ({ revalidate : 60 })
return getUser (id)
}
export default async function Page ({ params }: { params: Promise <{ id: string }> } ) {
const { id } = await params
const user = await getCachedUser (id)
return <div > {user.name}</div >
}
No manual cache keys - use cache generates keys automatically from function arguments and closures. The keyParts array from unstable_cache is no longer needed.
Tags - Replace options.tags with cacheTag() calls inside the function.
Revalidation - Replace options.revalidate with cacheLife({ revalidate: N }) or a built-in profile like cacheLife('minutes').
Dynamic data - unstable_cache did not support cookies() or headers() inside the callback. The same restriction applies to use cache, but you can use 'use cache: private' if needed.
Limitations
Edge runtime not supported - requires Node.js
Static export not supported - needs server
Non-deterministic values (Math.random(), Date.now()) execute once at build time inside use cache
For request-time randomness outside cache:
import { connection } from 'next/server'
async function DynamicContent ( ) {
await connection ()
const id = crypto.randomUUID ()
return <div > {id}</div >
}