尝试使用 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