进阶能力
TanStack Query 的进阶能力,主要集中在这些方向:
- 缓存生命周期
- 后台重取策略
- 乐观更新
- 查询依赖
- 预取
- SSR 与 hydration
查询依赖
一个查询依赖另一个查询结果时,enabled 仍然是最稳的入口。
后台重取
常见选项:
refetchOnWindowFocusrefetchOnReconnectrefetchInterval
这些选项不是越多越好。后 台系统、监控面板、消息列表的策略通常都不一样。
预取
官方文档一直把 prefetchQuery 放在很靠前的位置,因为它解决的问题很直接:页面还没切过去,数据已经先进缓存了。
await queryClient.prefetchQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
})
一个更实际的场景是:
- 鼠标移到详情按钮时预取详情
- 路由跳转前预取下一页列表
- 首屏渲染前在服务端预取关键查询
SSR 与 hydration
TanStack Query 的 SSR 主线一直很清楚:
- 服务端创建新的
QueryClient - 先
prefetchQuery - 用
dehydrate导出缓存状态 - 客户端再用
hydrate或HydrationBoundary接回去
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 侧官方文档里,dehydrate 和 hydrate 是同一条主线:
import { dehydrate, hydrate } from '@tanstack/vue-query'
更关键的不是 API 名字,而是边界:
- 每个服务端请求都要用新的
QueryClient - 不要把服务端缓存错误共享给别的请求
- 传给客户端前要确认序列化边界
hydration 最容易踩的点
1. 服务端和客户端不是同一个缓存实例
这本来就是正常结构。更需要确认的是:客户端拿到的 dehydrated state,和服务端渲染时用的是同一份数据快照。
2. 只预取一部分查询
这通常没问题。官方也明确提到,可以只预取关键查询,其他查询留给客户端自己拉。
3. 预取后没有及时清理服务端缓存
服务端场景里,缓存如果不按请求隔离,容易出现用户之间数据串掉的问题。
更适合先站稳的前提
这些进阶能力要发挥作用,前提还是基础层已经写稳:
- queryKey 清楚
- 请求层分层清楚
- 列表和详情的失效策略清楚
这些没理顺之前,先别急着把高级特性全堆上去。