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

Next.js 13.3 App目录下SWR无法每次请求更新数据问题

问题分析与解决方案

核心原因

  1. App Router API路由默认静态缓存:Next.js 13 App目录下的route.ts默认会被静态优化,即使你在fetch中设置了cache: "no-cache",Next.js仍会缓存API响应,导致后续请求复用旧数据。
  2. SWR默认缓存策略:SWR会将数据缓存到内存和本地存储,页面刷新时优先读取缓存,不会自动触发重新请求。

而Next.js 12的Pages Router中,API路由默认是动态的,不会静态缓存,同时页面刷新时SWR的缓存会被重置,所以能正常更新数据。

解决方案

1. 禁用API路由的静态缓存

在api/hello/route.ts中添加revalidate: 0,强制API路由每次请求都重新获取数据:

import { NextResponse } from 'next/server';

export const revalidate = 0; // 关键:禁用静态缓存

export async function GET(request: Request) {
  const response = await fetch(
    "https://timeapi.io/api/Time/current/zone?timeZone=Europe/Kiev",
    { cache: "no-cache" }
  );

  const data = await response.json();
  console.log(data);

  return NextResponse.json(data);
}

2. 配置SWR强制重新验证

在time.tsx中调整SWR的配置,确保每次页面加载/刷新时都重新请求数据:

"use client";

import useSWR from "swr";
import { fetcher } from "~/lib/fetcher";

export const Time = () => {
    const { data, error, isLoading } = useSWR("api/hello", fetcher, {
      revalidateOnMount: true, // 组件挂载时强制重新验证
      revalidateOnFocus: true, // 页面重新获得焦点时刷新数据
      dedupingInterval: 0, // 禁用请求去重,确保每次请求都发新请求
    });

  if (error) {
    return <div>error</div>;
  }

  if (isLoading) return <div>loading...</div>;

  console.log(data);
  return (
    <div>
      <div>{data.dateTime}</div>
    </div>
  );
};

3. 可选:验证页面组件的动态渲染

你的page.tsx已经设置了export const revalidate = 0,这确保了页面本身是动态渲染的,虽然客户端组件的SWR请求不受此直接影响,但保持这个配置可以避免页面静态缓存带来的其他问题。

验证效果

修改后,刷新页面时,API路由会重新调用timeapi.io获取最新时间,SWR也会放弃缓存重新请求,最终页面会显示最新的日期时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:23:11