ReactQuery的基本使用

Jun 29, 2024· 6 min read

React Query Demo

概述

React Query 是一个强大的数据获取和状态管理库,专为 React 应用而设计。 它简化了数据获取、缓存、同步和更新的复杂流程,使得开发者可以更加专注于业务逻辑。 本文将介绍 React Query 的基础使用方法,帮助你快速上手。

安装

SH
npm i @tanstack/react-query # or pnpm add @tanstack/react-query # or yarn add @tanstack/react-query # or bun add @tanstack/react-query

使用

配置 QueryClient

在使用 React Query 之前,需要先配置一个 QueryClient 实例。这个实例负责管理应用中的所有查询。

在你的应用的根组件中配置 QueryClient 和 QueryClientProvider:

TSX
// main.tsx import React from 'react'; import ReactDOM from 'react-dom/client'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import App from './App.tsx'; const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 3, // 重试次数 staleTime: 10 * 60 * 1000, // 过期时间 gcTime: 10 * 60 * 1000, // 垃圾回收时间 refetchOnWindowFocus: false // 窗口聚焦时是否重新获取数据 } } }); ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <QueryClientProvider client={queryClient}> <App /> </QueryClientProvider> </React.StrictMode> );
  • defaultOptions 这里可以指定全局的默认配置,如果单独针对某个接口可单独设置。
  • retry 接口获取失败后重试次数,并不包含首次获取
  • staleTime 用于指定从数据被获取后的一段时间内是新鲜的(fresh),数据在指定时间内不被认为是陈旧的
  • gcTime 用于指定数据变为不活跃(inactive),过期后的一段时间内没有被调用就会被垃圾回收,之前的字段是cacheTime,由于容易混淆含义改为了gcTime
  • refetchOnWindowFocus 窗口重新获得焦点时是否重新获取数据

当然defaultOptions远远不止这些配置,这里只介绍了常见的几种配置,如需更加细致的配置请查看官网

查询

使用 useQuery 钩子来进行数据查询。假设我们要获取一个用户的数据,可以这样写

TSX
const { isFetching, data, refetch, isLoading, isError, isPending } = useQuery({ queryKey: ['post'], queryFn: (): Promise<Post[]> => request.get('/posts', { params: { _start: 1, _limit: 5 } }) });

useQuery的主要参数含义

  • queryKey 用于标识这个查询的唯一标识,如果有查询参数的话可以把查询参数也写上 queryKey: ['post', params]
  • queryFn 查询数据调用的函数

可以看到 useQuery 返回了非常多的参数,下面让我们详细了解下这些常用的参数具体含义

  • data 接口获取的数据
  • isFetching 接口是否在请求中,每次接口请求都会发生变化
  • isLoading 接口是否在加载中,只会在首次请求的时候会发生变化
  • isError 接口是否请求失败
  • isPending 接口是否在阻塞状态
  • refetch 重新获取数据的方法,用于手动获取数据

isLoading 只有在缓存中没有的时候获取数据时才为 true isFetching 每次获取数据时都是 true

变更

TSX
const queryClient = useQueryClient(); const { mutateAsync: createPostAsync } = useMutation({ mutationKey: ['post-create'], mutationFn: (params: Post) => request.post('/posts', params), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['post'] }); } }); const create = () => { createPostAsync({ id: Date.now() + '', title: 'New Post', views: 0 }); }; const { mutateAsync: removePostAsync } = useMutation({ mutationKey: ['post-delete'], mutationFn: (id: string) => request.delete(`/posts/${id}`), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['post'] }); } }); const remove = (id: string) => { removePostAsync(id); };

以上代码描述了创建和新增一条 post,其中我们都是使用的解构出来的mutateAsync, 其实有个mutate跟它作用是一样的,他们两的区别是mutateAsync 是一个Promise, 更加方便我们对其进行操作。

我们设置了mutationKey, mutationFn, onSuccess 参数,下面具体说下这些参数的作用

  • mutationKeymutationFnuseQuery中差不多一个含义
  • onSuccess 用于指定接口调用成功后的回调函数
TS
queryClient.invalidateQueries({ queryKey: ['post'] });

可以看到在createremove操作中我们都在onSuccess 中干了同一件事, 那就是重新获取post列表,在这里我们仅需要把想要重新获取数据的queryKey添加进去就行了

总结

React Query 是我们可以更加方便的管理数据获取和状态管理,以上只是常见的使用方式,如果想深入了解更多高级特性, 如分页,乐观更新、数据预获取等,请查看官网。