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

Next.js 14 SSG构建未用getStaticProps却触发API请求?

构建时触发API请求的原因及解决办法

核心原因

Next.js 14的PageRouter对于无动态逻辑的静态页面(没使用getServerSideProps/动态路由,也没显式禁用静态优化),默认会在构建阶段执行静态预渲染——也就是把组件渲染成静态HTML文件。

而react-query v5的useSuspenseQuery是渲染触发型的钩子:只要组件渲染到这个钩子,且没有可用的缓存数据,就会立即执行传入的查询函数(也就是你的getHealthCheck接口调用)。在构建预渲染过程中,React会遍历整个组件树(包括Suspense包裹的Test组件),触发数据获取逻辑来生成完整的静态页面内容,哪怕你用了Suspense做加载状态处理,构建时还是会等待接口返回结果,所以终端会打印axios里的console.log。

解决办法

根据你的需求,可选以下几种方案:

  • 仅在客户端执行查询:给useSuspenseQuery添加enabled条件,限制只有在浏览器环境才触发请求:
    useSuspenseQuery({
      queryKey: ['healthCheck'],
      queryFn: getHealthCheck,
      enabled: typeof window !== 'undefined' // 仅客户端启用
    })
    
  • 禁用页面静态优化:如果该页面不需要静态预渲染,在index.tsx中添加导出配置强制动态渲染,这样构建时不会预渲染组件,也就不会触发API请求:
    export const dynamic = 'force-dynamic'
    
  • 提前填充构建时缓存:如果需要保留静态预渲染,但不想调用真实接口,可以在_app.tsx中初始化react-query缓存,提前填入getHealthCheck的模拟数据,这样useSuspenseQuery会直接读取缓存而不触发请求:
    import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
    
    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          cacheTime: Infinity,
        },
      },
    })
    
    // 构建时预填充缓存
    if (typeof window === 'undefined') {
      queryClient.setQueryData(['healthCheck'], { status: 'ok' }) // 模拟接口返回数据
    }
    
    function MyApp({ Component, pageProps }) {
      return (
        <QueryClientProvider client={queryClient}>
          <Component {...pageProps} />
        </QueryClientProvider>
      )
    }
    
    export default MyApp
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:32:40