You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Next.js应用中Fetch请求缓存导致数据不更新的问题?

Next.js 13.8/14数据不更新问题排查与解决

问题背景

项目中通过Fetch API从MongoDB获取参与者列表,本地开发环境、Netlify生产环境运行正常,但本地生产构建后及Vercel部署后,仅首次请求能获取最新数据,页面刷新后数据无更新。已尝试设置{cache: no-cache}和revalidate,未解决问题。

核心原因

Next.js App Router默认采用静态缓存策略,生产环境下会静态化API路由和组件,即使前端请求设置了缓存禁用,静态生成的内容仍会被复用,导致数据不更新。

解决方案

1. 强制API路由动态化(关键步骤)

在API路由文件app/api/participants/all/route.js中,显式禁用静态缓存,添加动态路由标识:

import connectToDb from '@utils/connectToDb'
import Participant from '@models/Participant'

// 强制路由动态生成,每次请求都重新执行
export const dynamic = 'force-dynamic';
// 或设置revalidate: 0,效果一致
// export const revalidate = 0;

export const GET = async () => {
    try {
        await connectToDb()
        const allParticipants = await Participant.find()
        // 修复响应格式:status作为Response的第二个参数属性,而非JSON内容
        return new Response(JSON.stringify({allParticipants, success: true}), { status: 200 })
        
    } catch (error) {
        console.log(error, ' error in route GET');
        return new Response(JSON.stringify({error}), { success: false, status: 405 })
    }
}

注意:原代码中把status放在JSON响应体内是错误的,需移至Response的配置参数中,确保HTTP状态码正确返回。

2. 强化前端Fetch请求的缓存禁用

修改actions/index.js中的请求配置,使用更严格的no-store缓存策略,并添加Next.js专属的revalidate配置:

export const fetchAllParticipants = async () => {
  try {
    const response = await fetch("/api/participants/all", {
      cache: 'no-store', // 彻底禁止缓存,不存储任何请求/响应数据
      next: { revalidate: 0 }, // 告知Next.js无需缓存该请求结果
    });
    const data = await response.json();
    return data.allParticipants;
  } catch (error) {
    console.log(error);
  }
};

no-store比no-cache更严格:no-cache允许协商缓存(会向服务器验证资源是否更新),而no-store直接跳过所有缓存逻辑。

3. 强制组件动态渲染

如果使用该数据的组件是静态生成的,需在组件文件顶部添加动态渲染标识,确保每次页面请求都重新执行组件逻辑:

// 在组件文件最顶部添加
export const dynamic = 'force-dynamic';

const [participants, setParticipants]  = useState([]);

const fetchParticipants = async () => {
  try {
    const fetchedParticipants = await fetchAllParticipants();
    fetchedParticipants.sort((a, b) => a.serial - b.serial);
    setParticipants(fetchedParticipants);
  } catch (error) {
    console.log(error);
  }
};

useEffect(() => {
  fetchParticipants();
}, []);

验证方案

  1. 本地执行npm run build后启动生产服务,测试页面刷新是否能获取最新数据
  2. 重新部署至Vercel,验证线上环境的数据更新逻辑

内容的提问来源于stack exchange,提问作者Suhail PM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:35:00