03. Data Loading 与缓存:少一点魔法,多一点可追踪性

TanStack 的数据模型不是“比 Next 自动”。它的优势恰好是没那么自动:loader、Query、HTTP cache、Cloudflare cache 各管各的。

三层分工

适合放什么不适合放什么
TanStack Router loader cache路由进入前必须有的数据;按 path/search key 缓存跨多个路由共享、复杂 mutation、乐观更新
TanStack Query共享 server state、mutation、invalidate、分页、后台同步纯路由守卫、简单一次性页面数据
Cloudflare/HTTP cache公开、可按 Cache-Control 缓存的响应用户私有数据、强一致写后读

Next.js 背景下最容易误判的点

Next 的缓存常与 fetch、RSC、route cache、router cache 绑在一起。TanStack 的建议更接近:缓存是数据层选择,不是框架替你盖章。

export const Route = createFileRoute('/posts/$postId')({
  loader: async ({ params }) => fetchPost(params.postId),
  staleTime: 10_000,
  gcTime: 5 * 60_000,
})

什么时候用 Router loader,什么时候用 Query?

陷阱:“TanStack Router 有 cache,所以不需要 Query。”错。Router cache 是路由级 SWR;Query 是 server state 系统。把瑞士军刀当手术刀,病人和工具都会不高兴。

Cloudflare 上的额外判断

如果数据可公开缓存,优先考虑标准 HTTP cache headers,让 Cloudflare 边缘缓存工作。用户私有数据则走 server functions + D1/KV/R2,并明确认证和缓存边界。

快速判断

一个用户 dashboard 的多个 widget 共享同一份 account 数据,并会被 mutation 更新。优先用什么管理?

推荐原文

TanStack Query Overview 与 Router Data Loading。