tanstack query (react query)快速入门

注意:本文章基于@tanstack/react-query@5.90.2

介绍

tanstack query (原react query)是一个异步状态库,核心功能是从服务器获取、缓存、同步与更新状态从而摆脱手动发送网络请求。

tanstack query通过QueryClient管理缓存,并在合适的时候重新获取/刷新/回收缓存,缓存在QueryClient中以键值对的方式存在(键的类型为(string|number|undefined)[])

快速入门

安装

1
2
npm i @tanstack/react-query
npm i @tanstack/react-query-devtools --save-dev

启用tanstack query

创建一个QueryClient对象并使用QueryClientProvider导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const queryClient = new QueryClient(
{
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: 3,
staleTime: 1000 * 60 * 10, // 生存时间
gcTime: 1000 * 60 * 30, // 回收时间
},
},
}
)

createRoot(document.getElementById('root')!).render(
<StrictMode>
<QueryClientProvider
client={queryClient}
>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</StrictMode>,
)

注意:不同QueryClient实例之间不共享缓存

请求状态

1
2
3
4
5
6
const { data, isLoading, error } = useQuery({
queryKey: ['todos', page], //缓存条目的键
queryFn: () => fetchTodos(page), //请求函数
staleTime: 5000, // 5 秒内视为新鲜
gcTime: 300000, // 5 分钟无订阅后回收
});

修改状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const Example:React.FC = () => {
const mutation = useMutation({
mutationFn: updateTodo,
onMutate: (variables, context) => {
// A mutation is about to happen!

// Optionally return a result containing data to use when for example rolling back
return { id: 1 }
},
onError: (error, variables, onMutateResult, context) => {
// An error happened!
console.log(`rolling back optimistic update with id ${onMutateResult.id}`)
},
onSuccess: (data, variables, onMutateResult, context) => {
// Boom baby!
},
onSettled: (data, error, variables, onMutateResult, context) => {
// Error or success... doesn't matter!
queryClient.invalidateQueries({
queryKey: ["key"]
})//刷新指定条目缓存
},
});

return (
<button onClick={mutation.mutate} />
)
}
  • mutationFn:一个异步函数,用于执行修改数据的网络请求
  • onMutate:在mutationFn被执行前执行,一般用于乐观更新
  • onSettled:无论mutationFn执行成功或失败都会执行

返回值mutation含有以下属性:

  • mutate:执行变更,可通过mutate传入mutationFn的参数
  • mutateAsync:执行变更,异步执行,参数同上
  • state:当前状态
  • isIdle 或 status === ‘idle’:当前处于空闲或已重置状态
  • isPending 或 status === ‘pending’:变更正在执行
  • isError 或 status === ‘error’:变更过程中发生了错误
  • isSuccess 或 status === ‘success’:变更成功,结果数据可用
  • 除此之外,根据状态不同,还可以获取额外信息:
  • error:当状态为 error 时,通过此属性获取错误对象
  • data:当状态为 success 时,通过此属性获取结果数据

在非react组建中查询状态

1
2
3
4
queryClient.fetchQuery({
queryKey: ["user", userId],
queryFn: () => getUserInfo(userId),
})

注意:此处queryClient与入口处QueryClientProvider提供的应该为同一对象,否则无法共享缓存

持久化缓存

安装插件:

1
npm install @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client

将普通QueryClientProvider替换成PersistQueryClientProvider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister'

const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 60 * 60 * 24, // 24 hours
},
},
})

const persister = createAsyncStoragePersister({
storage: window.localStorage,
})

ReactDOM.createRoot(rootElement).render(
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister }}
>
<App />
</PersistQueryClientProvider>,
)

注:为了最大化利用缓存,建议将gcTime设置成大于等于maxAge(Persister缓存过期时间)