Next.js 13.4中如何为数据库调用添加revalidateTag标签?
解决Next.js 13.4数据库更新后页面缓存同步问题
针对你遇到的逐个调用revalidatePath过于繁琐、偶尔需要手动刷新的问题,用revalidateTag配合缓存标签是更高效的方案,以下是具体实现步骤:
1. 为数据库查询添加缓存标签
Next.js的unstable_cache函数可以为直接的数据库查询(非fetch请求)添加缓存标签,后续就能通过revalidateTag批量失效相关缓存:
示例:封装带缓存标签的数据库查询
import { unstable_cache } from 'next/cache'; import { kysely } from '@/db'; // 你的Kysely实例 // 任务列表查询:关联'tasks'标签 const getTasks = unstable_cache( async () => { return await kysely.selectFrom('task').selectAll().execute(); }, ['tasks-all'], // 唯一缓存键 { tags: ['tasks'] } // 绑定的缓存标签 ); // 单个任务查询:关联'tasks'和'task-{id}'标签 const getTaskById = unstable_cache( async (taskId: number) => { return await kysely .selectFrom('task') .selectAll() .where('id', '=', taskId) .executeTakeFirst(); }, (taskId) => [`task-detail-${taskId}`], // 动态生成缓存键 { tags: (taskId) => ['tasks', `task-${taskId}`] } // 绑定多个标签 ); // 在Server Component中使用这些查询函数 export default async function TasksPage() { const tasks = await getTasks(); // 渲染任务列表... }
2. 在更新操作中使用revalidateTag替换多个revalidatePath
修改你的Server Action,不用逐个验证路由,直接调用revalidateTag失效所有关联标签的缓存:
export default async function TaskEditPage({ params }: TaskPageProps) { async function editTask(formData: FormData) { "use server"; // 数据验证逻辑... const data = { title: formData.get('title') as string, description: formData.get('description') as string, priority: formData.get('priority') as string, finished_at: formData.get('finished_at') ? new Date(formData.get('finished_at') as string) : null, }; await kysely .updateTable("task") .set(data) .where("id", "=", Number(params.id)) .execute(); // 仅需两行,替代多个revalidatePath revalidateTag('tasks'); // 失效所有任务列表相关缓存 revalidateTag(`task-${params.id}`); // 失效当前任务的详情/编辑页缓存 // 注意:检查路径是否正确,原代码中是/ssr/task/${params.id},可能应为/ssr/tasks/${params.id} redirect(`/ssr/tasks/${params.id}`); } // 渲染编辑页面... }
其他可选方案
- 定时ISR刷新:如你提到的,在页面组件中添加
export const revalidate = 60;,让页面每60秒自动重新验证,但这种方式不如revalidateTag精准,可能会有延迟。 - 强制动态渲染:如果不需要缓存,可以在页面组件中添加
export const dynamic = 'force-dynamic';,这样每次请求都会重新查询数据库,但会牺牲缓存带来的性能优势。
注意事项
unstable_cache虽然带有unstable前缀,但在Next.js 13.4+版本中已经被广泛使用,后续大概率会稳定为正式API。- 确保所有使用任务数据的Server Component都通过封装后的查询函数获取数据,这样缓存标签才能生效。
内容的提问来源于stack exchange,提问作者manasseh stam
相关产品推荐
相关产品推荐

