
























在 React 里拉接口,最朴素的做法是 useEffect + useState:loading、error、data 自己维护,还要处理重复请求、切换页面再回来要不要重新拉等问题。TanStack React Query(原 React Query)把这些抽成一套约定,其中 useQuery 是最常用的「读数据」入口。
useQuery 是干什么的?一句话:在组件里声明「我要某份数据」,库里帮你 发请求、缓存、更新 UI 状态、按需重试 / 重拉。
你写的主要就两样:
queryKey:这份数据在缓存里的「身份证」(还能带上参数,变了就算另一份数据)。queryFn:真正去请求的异步函数(一般里面 fetch),成功返回值进缓存失败进错误。组件里直接用 data、isLoading、error 渲染即可。
它特别适合:列表、详情、用户信息、行情 这类「可读、可被缓存」的数据。(写操作用 useMutation,这里不展开。)
queryKey、queryFn、返回值queryKey["markets", limit, categoryId]。**queryKey** 里任一项变了 = 这是一条「新查询」,会重新跑 queryFn`(或使用新缓存)。习惯把 所有会影响请求结果的变量都放进 key,避免「参数变了却还在用旧数据」。
queryFnPromise,resolve 的结果就是 data 的类型。throw Error(或 rejection),React Query 会记成 error,并可用 retry 重试。在 TypeScript 里常写成:
这样 data 推断更稳。
data:最后一次成功拿到的数据(未成功前多为 undefined)。isLoading:「还没有可用的缓存且正在初次拉取」时为 true(语义随 v5 略有细化,可查官方文档)。isFetching:只要在读(含后台刷新)就为 true。error:失败时的错误。refetch:手动再拉一手。还有更多字段(status、fetchStatus、isStale…),按需查文档。
useMarkets 怎么对上号?示例(简化):
含义大致是:
queryKey 带 limit、categoryId:分类或条数一变,markets 就当新的一组缓存重新拉。staleTime:数据在这段时间内可能被当成「尚且新鲜」,减少无意义刷新(具体行为结合 refetch 策略)。refetchInterval:定时自动再跑 queryFn,适合做 短时轮询(例如价格和列表)。这正是「手写 useEffect + setInterval」里容易漏边界的地方,库里帮你收口。
useEffect 的常见对比(心智模型)useEffect:「挂载 / 依赖变了以后,执行一段副作用」——你完全自己管请求与状态。useQuery:「我声明 queryKey + 如何取数,库负责 缓存生命周期 + 异步状态」。不是「替换所有 useEffect」,而是 凡是以服务端数据为主的读模型,优先用 Query。
queryFn 里不要用 props 却没写进 queryKey:会用到旧闭包变量,或缓存错乱。ReactQueryProvider 示例。throw,否则 React Query 以为「成功了」。useQuery = queryKey(我是谁) + queryFn(怎么取)。useMarkets 一样:同一套机制既能拉 Gamma 聚合列表,又能定时补 CLOB 价格,而组件只消费 data / isLoading。若要进阶,可查官方文档里的:invalidateQueries(mutation 后作废缓存)、queryClient.prefetchQuery(预取)、placeholderData / keepPreviousData(分页体验)。
如果你希望这篇落到仓库里(例如 docs/blog-react-query-useQuery.md),可以说一声我按你文档风格再排版一版并保存路径。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。