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

Next.js 14 + React Query实现SSR异常:无服务端渲染效果

排查React Query + Next.js App Router SSR失效问题

以下是导致SSR未生效的核心问题及修复方案:

1. QueryClient实例不共享(核心问题)

RootLayout中创建的用于预取/脱水的QueryClient,和客户端Providers里创建的QueryClient是完全独立的实例,服务器预取的状态无法被客户端复用,导致客户端会重新发起请求。

修复方案:
将HydrationBoundary移到QueryClientProvider内部,确保两者使用同一个QueryClient实例;同时在客户端用服务器脱水的状态初始化QueryClient。

修改后的app/layout.tsx:

export default async function RootLayout({children}: {children: React.ReactNode}) {
  const queryClient = getQueryClient()
  const dehydratedState = dehydrate(queryClient)

  return (
    <html>
      <body>
          <Providers dehydratedState={dehydratedState}>
               {children}
          </Providers>
      </body>
    </html>
  )
}

修改后的Providers组件:

'use client'

import React, { useState } from 'react'
import { QueryClient, QueryClientProvider, HydrationBoundary } from '@tanstack/react-query'

function Providers({ children, dehydratedState }: React.PropsWithChildren<{ dehydratedState: any }>) {
  const [client] = useState(
    () => {
      const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000 } } })
      if (dehydratedState) {
        queryClient.hydrate(dehydratedState)
      }
      return queryClient
    }
  )

  return (
    <QueryClientProvider client={client}>
      <HydrationBoundary state={dehydratedState}>
        {children}
      </HydrationBoundary>
    </QueryClientProvider>
  )
}

export default Providers

2. 预取InfiniteQuery的配置与客户端Query不匹配

AdminUsersList中预取时,queryFn直接调用fetchUsers(0),没有遵循useInfiniteQuery的参数格式,且缺少getNextPageParam配置,导致预取的数据无法被客户端的useInfiniteQuery正确识别。

修复方案:
预取时完全对齐客户端useInfiniteQuery的配置:

export default async function AdminUsersList() {
  const queryClient = getQueryClient()
  await queryClient.prefetchInfiniteQuery({
    queryKey: ['users'],
    queryFn: ({ pageParam }) => fetchUsers(pageParam),
    initialPageParam: 0,
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  })

  return (
    <UserList />
  )
}

3. HydrationBoundary位置错误

原代码中HydrationBoundary在QueryClientProvider外部,无法访问客户端的QueryClient实例,无法完成状态复现。修复后已将其移动到QueryClientProvider内部(见Providers组件修改)。

验证SSR是否生效

修复后查看页面HTML源码,如果能直接看到用户列表内容(而非loading...),说明SSR已生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:33:32