数据缓存与重新验证方法

缓存是一种存储数据获取结果和其他计算的技术,使得未来对相同数据的请求可以更快响应,而无需重复执行相同工作。而重新验证则允许您更新缓存条目,无需重建整个应用程序。

Next.js 提供了几个 API 来处理缓存和重新验证。本指南将带您了解何时以及如何使用它们。

fetch

默认情况下,fetch 请求不会被缓存。您可以通过将 cache 选项设置为 'force-cache' 来缓存单个请求。

export default async function Page() {
  const data = await fetch('https://...', { cache: 'force-cache' })
}

须知:虽然 fetch 请求默认不缓存,但 Next.js 会对包含 fetch 请求的路由进行预渲染并缓存 HTML。如果您希望确保路由是动态的,请使用 connection API

要重新验证 fetch 请求返回的数据,可以使用 next.revalidate 选项。

export default async function Page() {
  const data = await fetch('https://...', { next: { revalidate: 3600 } })
}

这将按指定的秒数间隔重新验证数据。

查看 fetch API 参考文档了解更多。

unstable_cache

unstable_cache 允许您缓存数据库查询和其他异步函数的结果。要使用它,请用 unstable_cache 包裹函数。例如:

import { db } from '@/lib/db'
export async function getUserById(id: string) {
  return db
    .select()
    .from(users)
    .where(eq(users.id, id))
    .then((res) => res[0])
}
import { db } from '@/lib/db'

export async function getUserById(id) {
  return db
    .select()
    .from(users)
    .where(eq(users.id, id))
    .then((res) => res[0])
}

该函数接受第三个可选对象来定义缓存应如何重新验证。它包含:

  • tags:Next.js 用于重新验证缓存的标签数组。
  • revalidate:缓存应重新验证的秒数。
const getCachedUser = unstable_cache(
  async () => {
    return getUserById(userId)
  },
  [userId],
  {
    tags: ['user'],
    revalidate: 3600,
  }
)

查看 unstable_cache API 参考文档了解更多。

revalidateTag

revalidateTag 用于基于标签在事件发生后重新验证缓存条目。要与 fetch 一起使用,首先使用 next.tags 选项标记函数:

export async function getUserById(id: string) {
  const data = await fetch(`https://...`, {
    next: {
      tags: ['user'],
    },
  })
}

或者,您可以使用 tags 选项标记 unstable_cache 函数:

export const getUserById = unstable_cache(
  async (id: string) => {
    return db.query.users.findFirst({ where: eq(users.id, id) })
  },
  ['user'], // 如果变量未作为参数传递则需要
  {
    tags: ['user'],
  }
)

然后,在路由处理器或服务器操作中调用 revalidateTag

import { revalidateTag } from 'next/cache'

export async function updateUser(id: string) {
  // 修改数据
  revalidateTag('user')
}

您可以在多个函数中重复使用相同的标签,以便一次性重新验证它们。

查看 revalidateTag API 参考文档了解更多。

revalidatePath

revalidatePath 用于在事件发生后重新验证路由。要使用它,请在路由处理器或服务器操作中调用:

import { revalidatePath } from 'next/cache'

export async function updateUser(id: string) {
  // 修改数据
  revalidatePath('/profile')

查看 revalidatePath API 参考文档了解更多。

On this page