Next.js 数据获取与缓存

https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating

尝试使用 fetch 方法以及 server action 请求数据以及使用缓存。

fetch 方法设置缓存

https://nextjs.org/docs/app/api-reference/functions/fetch

Next.js 扩展了 fetch() API,允许服务器上的每个请求设置自己的持久性缓存。

async function getItem() {
  // 默认会进行缓存
  const res = await fetch('https://.../item/1')
  return res.json()
}

指定缓存时间:

// 缓存一个小时
fetch('https://...', { next: { revalidate: 3600 } })

也可以在 page.ts、route.ts 或 layout.ts 中指定导出的 revalidate 属性,影响该路由段所有 fetch 请求,不会覆盖 fetch 方法中指定的缓存属性。

// 缓存一个小时
export const revalidate = 3600

指定不启用缓存:

// 制定为不缓存
fetch(`https://...`, { cache: 'no-store' })

直接查数据库设置缓存

如果不通过 fetch 获取的数据,而是直接查询数据库,可使用 unstable_cache 来缓存。

第一个参数是一个异步函数,缓存的键会包含函数的传参。

import { unstable_cache } from 'next/cache';
 
const getCachedUser = unstable_cache(
  async (id) => getUser(id),
  ['my-app-user']
);

指定缓存时间,通过 unstable_cache 第三个参数 opts 的属性传入:

// 缓存一个小时
const getCachedUser = unstable_cache(
  async (id) => getUser(id),
  ['my-app-user'],
  { revalidate: 3600 }
);

刷新缓存

https://nextjs.org/docs/app/api-reference/functions/revalidatePath

可在 route.ts 路由处理程序或 server action 使用。

重新验证特定 URL:

import { revalidatePath } from 'next/cache'

revalidatePath('/')

动态路由可以使用字符串拼接:

revalidatePath('/blog/' + id)

缓存 tag

还有一种方式刷新缓存:

import { revalidateTag } from 'next/cache'
 
export default async function submit() {
  await addPost()
  revalidateTag('posts')
}

这个 tag 可以在 fetch 和 unstable_cache 中选项的 tags 来指定。

unstable_noStore 设置不缓存

在发起请求时调用,指定不缓存。

如果不想在调用时给 fetch 传参,例如 cache: 'no-store'next: { revalidate: 0 } ,则可以用作 noStore() 替代。

import { unstable_noStore as noStore } from 'next/cache';

export default async function Component() {
  noStore();
  const result = await db.query(...);
  // ...
}

route.ts 中的缓存

默认情况下,将 GET 方法与 Response 对象一起使用时,会应用缓存。

当 GET 方法接受参数 request 对象,或使用 cookies 和 headers ,或者其他 HTTP 方法,不会应用缓存。

也可以在 route.ts 导出路由段配置指定不应用缓存:

export const revalidate = false
本文收录于专栏
使用 Next.js 搭建 SSR 全栈 demo ,以及构建 SSG 纯静态博客,记录学习和使用笔记