前端项目越来越复杂,需要对接的后端接口也越来越多,处理这些数据的逻辑时常让人头大。之前一直听说 TanStack Query
在这方面现在还挺好用的,今天来简单认识一下一下。
概念
TanStack Query(以前称为 React Query)是一个强大的 数据获取和状态管理库,主要用于在前端应用中处理 服务端状态(Server State)。现在,它适用于 React、Solid、Vue、Svelte 等多个前端框架。它的核心理念是:让你专注于「数据的使用」,而不是「数据的管理」。
特性
特性 |
描述 |
数据缓存 |
自动缓存数据,避免重复请求 |
后台更新 |
数据过期后自动在后台更新 |
请求去重 |
相同请求不会重复发出 |
失败重试 |
网络失败时自动重试 |
自动刷新 |
可配置定时刷新数据 |
页面焦点/网络状态感知 |
页面激活或网络恢复时自动重新请求 |
开箱即用的状态管理 |
加载中 / 错误 / 成功等状态管理无需手写 |
场景
TanStack Query 主要解决「服务端状态管理」问题,比如:
- 拉取用户列表
- 获取文章详情
- 提交表单后重新获取数据
- 分页、无限滚动
- 多端数据同步等
而不适用于本地 UI 状态,如模态框开关、表单输入等(推荐使用 zustand、jotai 等本地状态库)。
基础使用
安装
1
| npm install @tanstack/react-query
|
创建 QueryClient
1 2 3 4 5 6 7 8 9 10 11
| import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
function App() { return ( <QueryClientProvider client={queryClient}> <MyComponent /> </QueryClientProvider> ) }
|
使用 useQuery 获取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { useQuery } from '@tanstack/react-query' import axios from 'axios'
function MyComponent() { const { data, isLoading, error } = useQuery({ queryKey: ['users'], queryFn: () => axios.get('/api/users').then(res => res.data), })
if (isLoading) return <div>加载中...</div> if (error) return <div>出错了!</div>
return ( <ul> {data.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ) }
|
常用功能
数据缓存
1 2 3 4 5 6
| useQuery({ queryKey: ['users'], queryFn: fetchUsers, cacheTime: 1000 * 60 * 5, staleTime: 1000 * 30, })
|
自动刷新
1 2 3 4 5
| useQuery({ queryKey: ['users'], queryFn: fetchUsers, refetchInterval: 5000, })
|
手动刷新
1 2 3 4 5
| const queryClient = useQueryClient()
<button onClick={() => queryClient.invalidateQueries(['users'])}> 手动刷新 </button>
|
依赖条件执行
1 2 3 4 5
| useQuery({ queryKey: ['user', userId], queryFn: () => fetchUserById(userId), enabled: !!userId, })
|
可以通过 React Query Devtools 观察所有 query 和 mutation 状态。
1
| npm install @tanstack/react-query-devtools
|
1 2 3 4 5 6
| import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
<QueryClientProvider client={queryClient}> <App /> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider>
|
提交后更新数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { useMutation, useQueryClient } from '@tanstack/react-query'
function CreateUser() { const queryClient = useQueryClient()
const mutation = useMutation({ mutationFn: (newUser) => axios.post('/api/users', newUser), onSuccess: () => { queryClient.invalidateQueries(['users']) }, })
return ( <button onClick={() => mutation.mutate({ name: '张三' })} > 创建用户 </button> ) }
|