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

Next.js中使用React Query发起依赖Next-Auth会话令牌的服务端查询

问题原因

你拿不到有效会话数据的核心原因是Hook执行时序和React Query默认行为的匹配问题:

  • Next Auth的useSession在客户端首次挂载时处于加载阶段:此时还未完成会话校验,返回的session值为undefined,直到校验完成、拿到完整会话信息后才会触发组件重渲染,填充真实的userData字段。
  • React Query的useInfiniteQuery默认在组件挂载后立即发起请求,不会等待异步的会话加载完成。第一次执行请求函数时,读到的session?.user?.userData就是undefined,自然拼出了/api?userData=undefined的错误路径。
  • 你把查询key写死为固定字符串'query',后续即使会话加载完成、userData更新为有效值,React Query也感知不到依赖变化,不会自动重新发起正确请求。你在页面中能读到会话值,只是因为会话加载完成后触发了重渲染,错误的请求早在第一次挂载时就已经发出去了。
正确实现方案

只需要做三处核心调整即可解决问题:

  • 读取useSession返回的加载状态,通过React Query的enabled配置项,强制等会话认证完成、userData存在时再发起查询请求。
  • 把请求依赖的userData加入React Query的查询key,保证userData变化时查询会自动重置、用新参数拉取数据。
  • 不要在queryFn的参数默认值中引用外部可变变量,避免闭包陷阱缓存旧值导致请求参数错误。

修正后的useApiData.ts代码如下:

// hooks/useApiData.ts
async function fetchPage(pageParam: string) {
   const res = await fetch(pageParam)
   if (!res.ok) throw new Error('接口请求失败')
   return res.json()
}

export default function useApiData() {
   const { data: session, status } = useSession()
   const userData = session?.user?.userData

   return useInfiniteQuery(
      // 查询key必须带上依赖的动态值,变化时自动触发重查
      ['apiDataList', userData],
      ({ pageParam }) => fetchPage(pageParam),
      {
         // 仅在会话认证完成、userData有效值存在时启用查询
         enabled: status === 'authenticated' && !!userData,
         // 初始请求地址,仅在查询启用时生效,此时userData一定有值
         initialPageParam: `/api?userData=${userData}`,
         getNextPageParam: (prevPage) => prevPage.next ?? undefined
      }
   )
}

额外注意:你原页面代码中调用的Hook名为useCourseData,和自定义Hook的文件名、导出名useApiData不一致,记得统一命名避免报错。现有页面的isLoading判断逻辑不需要修改,会话加载阶段查询不会启动,isLoading会保持false,等会话就绪开始发请求时会自动变成true,完全兼容现有加载态逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:24:30