跳到主要内容

进阶能力

TanStack Query 的进阶能力,主要集中在这些方向:

  • 缓存生命周期
  • 后台重取策略
  • 乐观更新
  • 查询依赖
  • 预取
  • SSR 与 hydration

查询依赖

一个查询依赖另一个查询结果时,enabled 仍然是最稳的入口。

后台重取

常见选项:

  • refetchOnWindowFocus
  • refetchOnReconnect
  • refetchInterval

这些选项不是越多越好。后台系统、监控面板、消息列表的策略通常都不一样。

预取

官方文档一直把 prefetchQuery 放在很靠前的位置,因为它解决的问题很直接:页面还没切过去,数据已经先进缓存了。

await queryClient.prefetchQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
})

一个更实际的场景是:

  • 鼠标移到详情按钮时预取详情
  • 路由跳转前预取下一页列表
  • 首屏渲染前在服务端预取关键查询

SSR 与 hydration

TanStack Query 的 SSR 主线一直很清楚:

  1. 服务端创建新的 QueryClient
  2. prefetchQuery
  3. dehydrate 导出缓存状态
  4. 客户端再用 hydrateHydrationBoundary 接回去

React 场景的典型结构

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

export async function getServerSideProps() {
const queryClient = new QueryClient()

await queryClient.prefetchQuery({
queryKey: ['posts'],
queryFn: getPosts,
})

return {
props: {
dehydratedState: dehydrate(queryClient),
},
}
}

客户端再把这份状态交给 HydrationBoundary 或对应的 hydration 组件。

Vue 场景的关键点

Vue 侧官方文档里,dehydratehydrate 是同一条主线:

import { dehydrate, hydrate } from '@tanstack/vue-query'

更关键的不是 API 名字,而是边界:

  • 每个服务端请求都要用新的 QueryClient
  • 不要把服务端缓存错误共享给别的请求
  • 传给客户端前要确认序列化边界

hydration 最容易踩的点

1. 服务端和客户端不是同一个缓存实例

这本来就是正常结构。更需要确认的是:客户端拿到的 dehydrated state,和服务端渲染时用的是同一份数据快照。

2. 只预取一部分查询

这通常没问题。官方也明确提到,可以只预取关键查询,其他查询留给客户端自己拉。

3. 预取后没有及时清理服务端缓存

服务端场景里,缓存如果不按请求隔离,容易出现用户之间数据串掉的问题。

更适合先站稳的前提

这些进阶能力要发挥作用,前提还是基础层已经写稳:

  • queryKey 清楚
  • 请求层分层清楚
  • 列表和详情的失效策略清楚

这些没理顺之前,先别急着把高级特性全堆上去。