Next.js 13.4 App Router列表缓存问题:如何实现自动/强制更新?
Next.js 13.4 App Router 列表缓存问题解决办法
场景1:每次进入路由自动刷新列表
App Router 中默认的 fetch 会缓存数据,静态渲染的页面在客户端导航时不会重新请求数据。要实现每次访问路由都获取最新数据,可通过以下两种方式解决:
方式1:修改fetch缓存配置
直接在 fetch 选项中添加 next: { revalidate: 0 }(等价于 cache: 'no-store'),强制每次请求都重新获取数据:
export default async function Page() { async function getData() { const response = await fetch("http://localhost:8000/v1/report", { headers: { "x-access-token": "token", }, next: { revalidate: 0 } // 禁用缓存,每次请求都拉取最新数据 }); return await response.json(); } const data = await getData(); return <div>{/* 渲染列表内容 */}</div>; }
方式2:页面级全局禁用缓存
在页面组件顶部导出 revalidate 常量并设为 0,整个页面的所有数据请求都会禁用缓存:
export const revalidate = 0; // 页面级禁用缓存 export default async function Page() { async function getData() { const response = await fetch("http://localhost:8000/v1/report", { headers: { "x-access-token": "token", }, }); return await response.json(); } const data = await getData(); return <div>{/* 渲染列表内容 */}</div>; }
场景2:执行CRUD操作后自动刷新列表
如果需要在用户完成新增/编辑/删除等操作后立即更新列表,可使用 Server Actions 结合 revalidatePath 清除页面缓存,触发数据重新获取:
步骤1:定义Server Action
在单独文件(如 app/actions.ts)中编写处理CRUD的Server Action,操作完成后调用 revalidatePath 清除对应页面缓存:
'use server'; import { revalidatePath } from 'next/cache'; // 示例:删除报表的Server Action export async function deleteReport(formData: FormData) { const id = formData.get('id') as string; // 调用外部API执行删除操作 const response = await fetch(`http://localhost:8000/v1/report/${id}`, { method: 'DELETE', headers: { "x-access-token": "token", }, }); if (!response.ok) { throw new Error('删除操作失败'); } // 清除列表页面缓存,触发数据重新获取 revalidatePath('/report'); // 替换为你的列表页面路由 }
步骤2:在页面中调用Server Action
在列表页面通过表单或按钮触发Server Action,操作完成后页面会自动加载最新数据:
export default async function Page() { async function getData() { const response = await fetch("http://localhost:8000/v1/report", { headers: { "x-access-token": "token", }, }); return await response.json(); } const data = await getData(); return ( <div> {data.map((item) => ( <div key={item.id}> <span>{item.title}</span> <form action={deleteReport}> <input type="hidden" name="id" value={item.id} /> <button type="submit">删除</button> </form> </div> ))} </div> ); }
补充:客户端组件方案(可选)
如果需要完全在客户端控制数据刷新,可将页面改为客户端组件,使用 useEffect 在组件挂载时获取数据:
'use client'; import { useState, useEffect } from 'react'; export default function Page() { const [data, setData] = useState([]); useEffect(() => { async function fetchData() { const response = await fetch("http://localhost:8000/v1/report", { headers: { "x-access-token": "token", }, cache: 'no-store' // 确保每次请求都获取最新数据 }); const result = await response.json(); setData(result); } fetchData(); }, []); return <div>{/* 渲染列表内容 */}</div>; }
内容的提问来源于stack exchange,提问作者dm707
相关产品推荐
相关产品推荐

