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

