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

Next.js 13构建时fetch被调用两次及静态页面数据变更问题

Next.js 13 fetch缓存相关问题解答

问题场景

使用Next.js 13的fetch并配置{cache:'force-cache'}调用随机笑话API时,构建过程中fetch被调用两次,且静态生成的页面点击刷新按钮后数据发生变化。

代码示例

// page.js
import {RefreshButton} from './RefreshButton'

async function getRandomJoke(){
  const res = await fetch("https://v2.jokeapi.dev/joke/Programming?type=single", {cache:'force-cache'})
  const data = await res.json()
  console.log("fetch called. Joke is: ", data['joke'])

  return data['joke']
}

export default async function Home() {
  const joke = await getRandomJoke()

  return (
    <div>
      {joke}
      <RefreshButton/>
    </div>
  )
}

构建日志

[=   ] info  - Generating static pages (2/3)fetch called. Joke is:  A programmer puts two glasses on his bedside table before going to sleep. A full one, in case he gets thirsty, and an empty one, in case he doesn't.

[==  ] info  - Generating static pages (2/3)fetch called. Joke is:  The generation of random numbers is too important to be left to chance.

核心问题

  1. 为何构建时fetch会被调用两次?
  2. 静态生成的页面刷新后数据为何会发生变化?

问题解答

1. 构建时fetch两次调用的原因

Next.js 13在静态生成(SSG)阶段存在两次渲染流程:

  • 第一次是数据收集阶段:Next.js会执行组件以识别所有数据依赖(比如fetch调用),此时会触发getRandomJoke函数执行一次fetch。
  • 第二次是正式静态页面生成阶段:基于收集到的依赖,再次执行组件生成最终的静态HTML内容,这会再次触发fetch调用。

虽然配置了{cache:'force-cache'},但在静态构建的这两次渲染过程中,缓存尚未被持久化到存储层,因此无法复用第一次请求的结果。加上API返回随机内容,所以两次请求得到不同的笑话。

2. 静态页面刷新后数据变化的原因

点击调用router.refresh()的按钮时,会触发Next.js的**增量静态再生(ISR)**机制:

  • 该操作会向服务器发起请求,重新执行页面组件的数据获取逻辑(即再次调用getRandomJoke),从API获取新的随机笑话。
  • 服务器会基于新的数据生成更新后的静态页面,并将其缓存。后续访问该页面时,会展示最新的内容,直到下一次触发再生操作。

内容的提问来源于stack exchange,提问作者utg.tdawg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:36:20