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

Next.js结合React Query的useQuery、getStaticPaths实现单ID详情查询

Next.js + React Query 实现SSG单ID详情查询方案

1. 先确认全局_app.js配置正确

这是React Query脱水/水合能力生效的基础,配置示例如下:

// 如果你使用React Query v3版本,将导入路径替换为 'react-query' 即可
import { QueryClient, QueryClientProvider, Hydrate } from '@tanstack/react-query'

// 全局初始化QueryClient
const queryClient = new QueryClient()

function MyApp({ Component, pageProps }) {
  return (
    <QueryClientProvider client={queryClient}>
      {/* 水合服务端预取的缓存数据 */}
      <Hydrate state={pageProps.dehydratedState}>
        <Component {...pageProps} />
      </Hydrate>
    </QueryClientProvider>
  )
}

export default MyApp

2. 动态路由页面实现(示例路径:pages/users/[id].js)

2.1 getStaticPaths预生成所有详情页路径

export async function getStaticPaths() {
  // 调用接口拉取全量用户ID,用于预生成所有详情页路径
  const res = await fetch('你的全量用户列表接口地址')
  const users = await res.json()

  const paths = users.map(user => ({
    params: { id: user.id.toString() } // 注意Next.js的params值默认是字符串,要和接口参数类型对齐
  }))

  return {
    paths,
    // fallback取值说明:
    // false:未预生成的路径直接返回404,适合用户量少的场景
    // 'blocking':未预生成的路径首次访问时服务端渲染后缓存,后续访问直接走静态资源,适合用户量较大的场景
    fallback: 'blocking'
  }
}

2.2 getStaticProps预取单用户数据并脱水

import { QueryClient, dehydrate } from '@tanstack/react-query'

export async function getStaticProps({ params }) {
  const queryClient = new QueryClient()
  // 预取单用户数据,queryKey必须和前端useQuery的queryKey完全一致
  await queryClient.prefetchQuery(['user', params.id], () => 
    fetch(`你的单用户详情接口地址/${params.id}`).then(res => res.json())
  )

  return {
    props: {
      // 传递脱水后的缓存到前端
      dehydratedState: dehydrate(queryClient),
      id: params.id // 可选,方便前端组件直接取用ID
    },
    revalidate: 86400 // 可选,增量静态更新的周期(单位秒),不需要可删除
  }
}

2.3 页面组件用useQuery消费缓存数据

import { useQuery } from '@tanstack/react-query'

function UserDetail({ id }) {
  // queryKey和服务端prefetch的key完全一致,会直接读取水合后的缓存,不会发起额外请求
  const { data: user, isLoading } = useQuery(['user', id], () => 
    fetch(`你的单用户详情接口地址/${id}`).then(res => res.json())
  )

  // fallback不是false的场景需要处理加载状态
  if (isLoading) return <div>加载中...</div>

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.description}</p>
    </div>
  )
}

export default UserDetail

常见问题排查

  • 前后端queryKey必须完全一致,包括参数顺序、数据类型(比如数字ID和字符串ID不匹配会导致缓存失效)
  • 如果不需要前端兜底请求,可以给useQuery添加enabled: false配置,完全依赖服务端预取的数据
  • 不要在getStaticProps里同时返回接口原始数据和dehydratedState,避免数据冗余

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:15:04