在NextJS App Router与服务端组件中结合Prisma使用revalidateTag
在Next 13 App Router中无需fetch即可用revalidateTag实现局部刷新
你当前代码里返回revalidateTag数组的方式是无效的,不用fetch也能实现特定标签的缓存重验证,而且不会触发全页刷新,核心是用Next.js提供的revalidateTag函数结合缓存标签来操作,具体如下:
关键步骤
- 首先要给需要刷新的数据库查询(或其他数据源)添加缓存标签,Next.js默认不会缓存Prisma这类直接的数据库操作,所以得用
unstable_cache包裹查询并指定标签 - 在服务器动作(带
"use server"的函数)里完成数据库操作后,直接调用revalidateTag触发对应标签的缓存失效,页面会自动更新关联的内容,无需全页刷新
修改后的完整代码
import { prisma } from "@/db"; import { revalidateTag, unstable_cache } from 'next/cache'; import { faker } from '@faker-js/faker'; // 用unstable_cache包裹用户查询,绑定'db'标签 const getUsers = unstable_cache( async () => prisma.user.findMany(), ['users-data'], // 唯一缓存键,用于区分不同缓存 { tags: ['db'] } // 关联重验证标签 ); export default async function Page() { // 获取缓存的用户数据 const users = await getUsers(); const addUser = async() => { "use server"; // 执行数据库操作 await prisma.user.create({ data: { email: faker.internet.email() } }); // 触发'db'标签的缓存失效 revalidateTag('db'); }; return( <> <form action={addUser}> <button type="submit">添加新用户</button> </form> <div> <h3>当前用户列表</h3> {users.map(user => ( <p key={user.id}>{user.email}</p> ))} </div> </> ); }
额外说明
- 服务器动作执行后,Next.js只会更新依赖
db标签缓存的部分,不会触发全页面刷新,也不需要额外的API路由或fetch调用 unstable_cache目前是实验性API,但在Next.js 13及以上版本可以稳定使用,后续官方可能会调整为稳定API- 如果是用fetch请求获取数据,可以直接在fetch选项里加
next: { tags: ['db'] },调用revalidateTag('db')同样会失效该fetch的缓存
内容的提问来源于stack exchange,提问作者P Savva
相关产品推荐
相关产品推荐

