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
相关产品推荐
相关产品推荐

