use cache
use cache
指令将组件和/或函数指定为可缓存的。它可以在文件顶部使用,以指示文件中的所有导出都是可缓存的,也可以在函数或组件的顶部内联使用,以告知 Next.js 应缓存返回值并在后续请求中重复使用。这是一个实验性的 Next.js 功能,而不是像 use client
或 use server
这样的原生 React 功能。
用法
通过在你的 next.config.ts
文件中使用 useCache
标志来启用对 use cache
指令的支持
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
useCache: true,
},
}
export default nextConfig
此外,当设置 dynamicIO
标志时,也会启用 use cache
指令。
然后,你可以在文件、组件或函数级别使用 use cache
指令
// File level
'use cache'
export default async function Page() {
// ...
}
// Component level
export async function MyComponent() {
'use cache'
return <></>
}
// Function level
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
须知
use cache
是一个实验性的 Next.js 功能,而不是像use client
或use server
这样的原生 React 功能。- 传递给缓存函数的任何可序列化 参数(或 props),以及它从父作用域读取的任何可序列化值,都将被转换为类似 JSON 的格式,并自动成为缓存键的一部分。
- 任何不可序列化的参数、props 或闭包值都将变成缓存函数内部的不透明引用,并且只能传递,而不能检查或修改。这些不可序列化的值将在请求时填充,并且不会成为缓存键的一部分。
- 例如,缓存函数可以将 JSX 作为
children
prop 接收,并返回<div>{children}</div>
,但它无法内省实际的children
对象。
- 例如,缓存函数可以将 JSX 作为
- 可缓存函数的返回值也必须是可序列化的。这确保了缓存的数据可以正确地存储和检索。
- 使用
use cache
指令的函数不得有任何副作用,例如修改状态、直接操作 DOM 或设置定时器以按时间间隔执行代码。 - 如果与 部分预渲染 一起使用,则具有
use cache
的段将作为静态 HTML shell 的一部分进行预渲染。 - 与仅支持 JSON 数据的
unstable_cache
不同,use cache
可以缓存 React 可以渲染的任何可序列化数据,包括组件的渲染输出。
示例
使用 use cache
缓存整个路由
要预渲染整个路由,请将 use cache
添加到 layout
和 page
文件**顶部**。这些段中的每一个都将被视为应用程序中的单独入口点,并将被独立缓存。
'use cache'
export default function Layout({ children }: { children: ReactNode }) {
return <div>{children}</div>
}
在 page
文件中导入和嵌套的任何组件都将继承 page
的缓存行为。
'use cache'
async function Users() {
const users = await fetch('/api/users')
// loop through users
}
export default function Page() {
return (
<main>
<Users />
</main>
)
}
对于以前使用
export const dynamic = "force-static"
选项的应用程序,建议这样做,并将确保整个路由被预渲染。
使用 use cache
缓存组件输出
你可以在组件级别使用 use cache
来缓存在该组件内执行的任何获取或计算。当你在整个应用程序中重用该组件时,只要 props 保持相同的结构,它就可以共享相同的缓存条目。
props 被序列化并构成缓存键的一部分,只要序列化的 props 在每个实例中产生相同的值,缓存条目就会被重用。
export async function Bookings({ type = 'haircut' }: BookingsProps) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
interface BookingsProps {
type: string
}
使用 use cache
缓存函数输出
由于你可以将 use cache
添加到任何异步函数,因此你不限于仅缓存组件或路由。你可能想要缓存网络请求或数据库查询,或者计算一些非常缓慢的内容。通过将 use cache
添加到包含此类工作的函数,它将变为可缓存的,并且在重用时将共享相同的缓存条目。
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
重新验证
默认情况下,当您使用 use cache
指令时,Next.js 设置 **15 分钟的重新验证周期**。Next.js 设置了接近无限的过期时间,这意味着它适用于不需要频繁更新的内容。
虽然此重新验证周期对于您不希望经常更改的内容可能很有用,但您可以使用 cacheLife
和 cacheTag
API 来配置缓存行为
这两个 API 都跨客户端和服务器缓存层集成,这意味着您可以在一个位置配置缓存语义,并使其应用于所有地方。
有关更多信息,请参阅 cacheLife
和 cacheTag
文档。
交错
如果您需要将不可序列化的参数传递给可缓存的函数,您可以将它们作为 children
传递。这意味着 children
引用可以更改,而不会影响缓存条目。
export default async function Page() {
const uncachedData = await getData()
return (
<CacheComponent>
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({ children }: { children: ReactNode }) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
您还可以通过缓存的组件将服务器行为传递到客户端组件,而无需在可缓存的函数内部调用它们。
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Perform some server-side update
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({
performUpdate,
}: {
performUpdate: () => Promise<void>
}) {
'use cache'
// Do not call performUpdate here
return <ClientComponent action={performUpdate} />
}
'use client'
export default function ClientComponent({
action,
}: {
action: () => Promise<void>
}) {
return <button onClick={action}>Update</button>
}
相关内容
这有帮助吗?