Query 与生态
很多人第一次对 TanStack 产生好感,其实不是从 Start 开始,而是从 Query 开始。
这很正常。TanStack Query 太常用了。它几乎已经成了“前端异步状态管理应该怎么做”的一条事实标准。
但如果你只把 TanStack 理解成 Query,那会少看掉后面一整条很顺的技术线。
1. Query 在整套体系里是什么位置
它解决的是:服务端状态怎么在前端应用里稳定地活着。
更具体一点:
- 请求之后怎么缓存
- 数据什么时候算旧
- 什么时候该重取
- 列表和详情怎么共享结果
- 写操作之后怎么失效
这一层和 fetch、axios 不是同一个问题,也和“我用不用 SSR 框架”不是同一个问题。
一个最小 QueryClient 配置
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 30_000,
gcTime: 5 * 60_000,
retry: 2,
refetchOnWindowFocus: false,
},
mutations: {
retry: 1,
},
},
})
export function App() {
return (
<QueryClientProvider client={queryClient}>
<RouterApp />
</QueryClientProvider>
)
}
这类默认值很适合大多数业务后台。它不会神奇,但能让 Query 的行为先稳定下来。
一个最常见的查询写法
import { useQuery } from '@tanstack/react-query'
async function fetchUsers() {
const res = await fetch('/api/users')
if (!res.ok) {
throw new Error('用户列表获取失败')
}
return res.json() as Promise<Array<{ id: string; name: string }>>
}
export function UserList() {
const query = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
})
if (query.isPending) return <p>加载中...</p>
if (query.isError) return <p>{query.error.message}</p>
return (
<ul>
{query.data.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
如果你想补更完整的 Query 内容,这个站点里已经有一组现成专题:
2. Query 和 Router 怎么配
这两个库一起用时,体验通常很好,因为职责划分比较顺:
Router管页面切换、URL、Loader、预加载Query管异步状态、缓存生命周期、更新与失效