首页/文章/javascript

React Query 快速入门

2023-12-21
24999 分钟
...

很早之前就看到 React Query 在前端掘金圈子里火了一把,一直想学却因为种种原因没有开始。这一阵子闲下来了一些,快速学习了一下并且在自己的小项目里上手用了一番,体验非常不错。所以在这里以 React Query 为例写一篇 TanStack Query 小小的快速上手指南。

React Query

TanStack Query (FKA React Query) is often described as the missing data-fetching library for web applications, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your web applications a breeze.

TanStack Query(前称 React Query,在下文中我们也采用这个称呼)通常被形容为 Web 应用所缺失的数据请求库。更专业的说法是,他让你的 web 应用中的请求、缓存、同步与更新服务端状态更加轻而易举了。

从我这段时间的使用体验来看,其中对于请求与缓存的处理可以说是 React Query 给我带来的最显著的提升。

以这样一段请求为例👇🏻

function getListData() {
  return axios.get('https://xxxx');
}

function List() {
  
  const [data, setData] = useState([])
  
  const [loading, setLoading] = useState(false)
  

  const queryData = () => {
    setLoading(true)
    getListData().then((res) => {
      
      setData(res.data.data)
    }).catch((error) => {
      
    }).finally(() => {
      setLoading(false)
    })
  }

  useEffect(() => {
    
    if (fulfilled) {
      queryData();
    }
  }, [])

  
  
}

使用 React Query 管理请求后,我们可以这样写(用过 ahooks 的 useRequest 的小伙伴应该很熟悉这种写法)

function List() {
  
  const { data, isFetching } = useQuery({
    queryFn: getListData, 
    queryKey: ["list", "query"], 
    enabled: fulfilled, 
  });

  
  
}

在外层,我们需要创建一个 QueryClient 并使用 QueryClientProvider 来提供一个查询的上下文。

const queryClient = new QueryClient()

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

我们把冗长的请求逻辑全部都交由 React Query 来帮我们处理,我们只需要关心请求的状态和数据即可。

更详细一些

让我们聚焦在例子中 useQuery 这个方法上

const { data, isFetching } = useQuery({
  queryFn: getListData, 
  queryKey: ["list", "query"], 
  enabled: fulfilled, 
});

入参

对于入参,这里我们就需要介绍一下 React Query 中最关键的两个参数:queryFnqueryKey

查询函数(queryFn)需要是能够返回 Promise 的任意函数。而该 Promise 的返回值将会被填充至 useQuery 返回的 结果数据 data 或是 错误 error

查询键(queryKey)需要是一个数组,其元素可以是任何可以被序列化的类型。

当然, React作为一个开箱即用的库,其本身还包含着一些默认配置。如果你发现 Devtool 的网络 tab 中时不时冒出来一个预期意外的请求。不要着急提Bug,这可能是以下几个默认开启的配置项在“搞鬼”。

  • refetchOnMount:在组件挂载时自动请求
  • refetchOnWindowFocus:在页面被重新focus时自动请求
  • refetchOnReconnect:网络重新连接时自动请求

除此之外,还有一种配置会导致重复的请求行为。不过这个需要手动开启,一般不会在开发者不知情的情况下触发请求。

  • refetchInterval:定时请求

对于那些默认的配置,你可以通过在 useQuery 的入参中关闭他们,或者在创建 queryClient 的时候就将他们全局关闭。

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnReconnect: false,
      refetchOnWindowFocus: false,
      
    },
  },
});

返回

对于 useQuery 返回的结果,一翻文档发现有25个属性

const {
	data,
	dataUpdatedAt,
	error,
	errorUpdateCount,
	errorUpdatedAt,
	failureCount,
	failureReason,
	fetchStatus,
	isError,
	isFetched,
	isFetchedAfterMount,
	isFetching,
	isInitialLoading,
	isLoading,
	isLoadingError,
	isPaused,
	isPlaceholderData,
	isPreviousData,
	isRefetchError,
	isRefetching,
	isStale,
	isSuccess,
	refetch,
	remove,
	status
} = useQuery(options);

大多数变量都可以见名知意,但是有一些细心的小伙伴可能发现了,这里的状态有非常多种,看起来貌似非常复杂。别急,让我们细细梳理一番。

在 React Query 中,我们有两个独立的状态 fetchStatusstatus ,分别对应请求本身的状态和结果的状态。什么意思嘞?

请求本身的状态 fetchStatus ,也就是指我们的请求函数 queryFn 的状态,它在执行还是在摸鱼?useQuery 给了我们以下几种状态。当 fetchStatus 为 xx 时,

  1. fetching:该请求函数正在卖力干活!对应 isFetching
  2. pause:请求函数本应干活,但是因为网络等原因被迫暂停了。对应 isPause
  3. idle:该请求函数正在卖力摸鱼(空闲)!对应 isIdle

status 则是对结果 data 的状态描述,我的数据是一个什么样的状态?当 status 为 xx 时,

  1. loading:你先别急,还没数据。对应 isLoading
  2. error:你的数据遇到了点错误,具体信息可以看看返回值中的error。对应 isError
  3. success:你的数据安全获取到了,存在 data 里啦。对应 isSuccess

这些状态一般来说就足以支撑我们绝大多数的场景了。

关于查询键

其实了解了上面的内容,已经可以开始上手开发了。不过对于查询键,咱还是想要多说两句。React Query 作为一个请求管理库,核心就是要将不同的请求统一管理。而对于不同的请求,React Query 通过唯一的 queryKey 来进行标识分组

举个🌰,对于这些个 query

const queryA = useQuery(["a1", "b1", "c1"], queryFnA);
const queryB = useQuery(["a1", "b1", "c2"], queryFnB);
const queryC = useQuery(["a1", "b2", "c1"], queryFnC);
const queryD = useQuery(["a2", "b1", "c1"], queryFnD);

你可以想象成 React Query 维护了这样的一个集合

在未来,我们需要用 React Query 的更高级的功能时,特别是对一些特定的 query 进行操作时,我们只需要通过 queryKey 就可以轻松查找到我们想要的 query 了。

例如我需要找出 queryA 和 queryB ,那么我就可以通过 ["a1", "b1"] 来筛选得到想要的结果。

所以,在设计或者编写 queryKey 的时候,建议“三思而后行”。

最后

到这里,这篇小小的指南也要走到尽头了,但 React Query 才刚刚开始,在本文中,我们只讨论了最基础的查询,如果你想实现更多场景,例如分页,无限滚动等。亦或是向服务端发送删除,更新一类的请求(useMutation)。还是需要在文档中继续学习一番。

这里还推荐一下修仙大橙子dalao的专栏,也可以配合文档食用~

在阅读 React Query 的文档时,我发现了这样一段话

Out of the box, TanStack Query is configured with aggressive but sane defaults. Sometimes these defaults can catch new users off guard or make learning/debugging difficult if they are unknown by the user.

TanStack 是开箱即用的,使用了一套侵入性但健全的出厂配置。如果不知道这些出厂配置的话,可能会使新用户猝不及防,或是让他们的学习和debug变得困难。

想到我很早之前想学习 React Query 的时候,也是受到了某些“坑”的影响,转身干别的事去了(不可取不可取)。我希望在读完这篇小小的指南后,可以帮助你们平缓地度过这一段陡坡~

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
javascript2026-02-24
navigator.sendBeacon全指南
在前端开发中,埋点系统是必不可少的一环。我们经常需要在用户 关闭页面 、 刷新 或 跳转路由 时,向服务器发送最后一条统计数据(比如用户停留时长、页面跳出率)。 但这看似简单的需求,在实现时却危机四伏:请求发不出去?页面跳转卡顿?今天我们就来聊聊这个问题的终极解决方案 —— 。 一、 痛点与传统方案的挣扎 场景还原 当用户点击关闭按钮时,浏览器会触发生命周期事件( 或 )。如果我们直接使用普通的异步 AJAX ( 或 ) 发送请求,浏览...
学习
javascript2025-11-02
理解浏览器事件系统,从用户点击到事件对象的完整旅程
深入理解浏览器事件系统:从用户点击到事件对象的完整旅程 “当我点击页面按钮时,背后发生了什么?为什么回调函数能收到一个包含丰富信息的event对象?今天,让我们一起揭开浏览器事件系统的神秘面纱。” 一个令人困惑的现象 作为前端开发者,我们每天都在写这样的代码: 这段代码如此熟悉,以至于我们很少停下来思考:​ ​这个 对象到底从哪里来?它为什么能知道点击的精确坐标?为什么能识别是哪个元素被点击了?​ ​ 更神奇的是,当我们手动创建事件时:...
学习
javascript2025-10-01
实现大文件上传全流程详解
在日常开发中,大文件上传是个绕不开的坎——动辄几百 MB 甚至 GB 级的文件,直接上传不仅容易超时,还会让用户体验大打折扣。最近我用 Vue+Express 实现了一套完整的大文件上传方案,支持分片上传、断点续传、秒传和手动中。 一、先看效果:我们要实现什么? 先上核心功能清单,确保大家明确目标,知道我们要解决哪些实际问题: 大文件分片上传 :将文件切成固定大小的小片段分批上传,避免单次请求超时 秒传 :服务器已存在完整文件时,直接返...
学习
javascript2025-09-18
JavaScript 的多线程能力:Worker
如果你写过一些计算量稍大的 JavaScript 代码,比如图像处理、大量数据排序或者复杂的算法,你几乎肯定遇到过浏览器“卡死”的现象。点击页面没反应,动画也停了,就像整个世界都静止了。 这就是主线程被阻塞的典型后果。因为主线程既要负责执行 JavaScript,又要负责渲染页面、响应用户操作,一旦它被繁重的计算任务占满,就无暇顾及其他,用户体验便直线下降。 这个问题的根源,正是“主线程是单线程的”。那么,如何解决呢? 答案很简单:把这...
学习面试
javascript2025-09-15
一张 8K 海报差点把首屏拖垮
你给后台管理系统加了一个「企业风采」模块,运营同学一口气上传了 200 张 8K 宣传海报。首屏直接飙到 8.3 s,LCP 红得发紫。 老板一句「能不能像朋友圈那样滑到哪看到哪?」——于是你把懒加载重新翻出来折腾了一轮。 解决方案:三条技术路线,你全踩了一遍 1\. 最偷懒:原生 一行代码就能跑,浏览器帮你搞定。 🔍 关键决策点 2020 年后现代浏览器全覆盖,IE 全军覆没。 必须写死 ,否则 CLS 会抖成 PPT。 适用场景...
学习
javascript2025-09-10
🚀 Web Worker让你的应用丝滑
🌟 引言 在日常的前端开发中,你是否遇到过这样的困扰: 大数据处理时页面卡死 :处理几万条数据时,页面直接卡成PPT,用户点击毫无反应 复杂计算阻塞UI :图片处理、数据分析等计算密集型任务让整个应用假死 文件上传/下载卡顿 :大文件操作时,其他功能完全无法使用 实时数据处理性能差 :WebSocket接收大量数据时,页面渲染严重滞后 今天分享6个Web Worker的核心技巧,让你的应用告别卡顿,用户体验丝滑如德芙! 💡 核心技巧...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录