use cache
use cache 指令允许您将路由、React 组件或函数标记为可缓存。它可以用于文件顶部,以指示文件中所有导出都应缓存,也可以内联在函数或组件顶部,以缓存其返回值。
须知:要缓存需要访问 cookies 或 headers 的用户特定内容,请参阅
'use cache: private'。
用法
use cache 是一项缓存组件功能。要启用它,请将 cacheComponents 选项添加到您的 next.config.ts 文件中
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  cacheComponents: true,
}
 
export default nextConfig然后,在文件、组件或函数级别添加 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 的工作原理
缓存键
缓存条目的键是使用其输入(包括以下内容)的序列化版本生成的
- 构建 ID(为每次构建生成)
- 函数 ID(函数特有的安全标识符)
- 可序列化 函数参数(或 props)。
传递给缓存函数的参数,以及它从父作用域读取的任何值都会自动成为键的一部分。这意味着,只要其输入相同,相同的缓存条目将被重用。
不可序列化的参数
任何不可序列化的参数、props 或闭包值都将在缓存函数内部转换为引用,并且只能通过,不能检查或修改。这些不可序列化值将在请求时填充,并且不会成为缓存键的一部分。
例如,缓存函数可以接受 JSX 作为 children prop 并返回 <div>{children}</div>,但它无法检查实际的 children 对象。这允许您将未缓存的内容嵌套在缓存组件中。
function CachedComponent({ children }: { children: ReactNode }) {
  'use cache'
  return <div>{children}</div>
}返回值
可缓存函数的返回值必须是可序列化的。这确保了缓存数据能够正确存储和检索。
在构建时使用 use cache
当在 布局 或 页面 顶部使用时,路由段将被预渲染,从而允许它以后进行重新验证。
这意味着 use cache 不能与 运行时数据(如 cookies 或 headers)一起使用。
注意:如果需要缓存依赖于 cookies、headers 或搜索参数的内容,请改用
'use cache: private'。
在运行时使用 use cache
在服务器上,单个组件或函数的缓存条目将缓存在内存中。
然后,在客户端,从服务器缓存返回的任何内容都将存储在浏览器内存中,直到会话结束或重新验证。
在重新验证期间
默认情况下,use cache 的服务器端重新验证周期为 15 分钟。虽然此周期可能适用于不需要频繁更新的内容,但您可以使用 cacheLife 和 cacheTag API 来配置何时应重新验证单个缓存条目。
这两个 API 都集成在客户端和服务器缓存层中,这意味着您可以在一个地方配置缓存语义,并将其应用到所有地方。
有关更多信息,请参阅 cacheLife 和 cacheTag API 文档。
示例
使用 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>
  )
}须知:
- 如果
use cache仅添加到layout或page,则只有该路由段及其导入的任何组件将被缓存。- 如果路由中任何嵌套的子组件使用 动态 API,则该路由将选择退出预渲染。
使用 use cache 缓存组件的输出
您可以在组件级别使用 use cache 来缓存该组件中执行的任何 fetches 或计算。只要序列化的 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 添加到任何异步函数,因此您不仅限于缓存组件或路由。您可能希望缓存网络请求、数据库查询或缓慢的计算。
export async function getData() {
  'use cache'
 
  const data = await fetch('/api/data')
  return data
}交错
在 React 中,使用 children 或 slot 的组合是构建灵活组件的众所周知的模式。当使用 use cache 时,您可以继续以这种方式组合您的 UI。作为 children 或其他组合 slot 包含在返回的 JSX 中的任何内容都将通过缓存组件传递,而不会影响其缓存条目。
只要您不直接在可缓存函数体内部引用任何 JSX slot,它们在返回输出中的存在就不会影响缓存条目。
export default async function Page() {
  const uncachedData = await getData()
  return (
    // Pass compositional slots as props, e.g. header and children
    <CacheComponent header={<h1>Home</h1>}>
      {/* DynamicComponent is provided as the children slot */}
      <DynamicComponent data={uncachedData} />
    </CacheComponent>
  )
}
 
async function CacheComponent({
  header, // header: a compositional slot, injected as a prop
  children, // children: another slot for nested composition
}: {
  header: ReactNode
  children: ReactNode
}) {
  'use cache'
  const cachedData = await fetch('/api/cached-data')
  return (
    <div>
      {header}
      <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>
}平台支持
| 部署选项 | 支持 | 
|---|---|
| Node.js 服务器 | 是 | 
| Docker 容器 | 是 | 
| 静态导出 | 否 | 
| 适配器 | 平台特定 | 
了解如何配置缓存,当自托管 Next.js 时。
版本历史
| 版本 | 更改 | 
|---|---|
| v16.0.0 | "use cache"已通过缓存组件功能启用。 | 
| v15.0.0 | "use cache"作为实验性功能推出。 | 
相关
use cache: private
cacheComponents
cacheLife
cacheTag
cacheLife
revalidateTag
这有帮助吗?