React Query 动态参数

date
Nov 5, 2025
slug
react-query-dynamic-parameters
status
Published
tags
React Query
summary
React Query 动态参数
type
Post
同学们,系好安全带!今天我们要从"温室花朵"进化成"丛林战士"了!
上节课我们学会了用 React Query 从静态 API 拿数据,就像去自动售货机买可乐——按个按钮,可乐就出来了。但现实世界的 API 更像是星巴克,你得告诉店员:"我要大杯、去冰、半糖、加燕麦奶、再加一份浓缩的拿铁"。

🎯 问题来了:动态参数

假设 GitHub API 支持排序,你可以按照仓库的创建时间、更新时间等来排序:
那么,我们的 useRepos Hook 该怎么接收这个排序参数呢?
你可能会这样写(❌ 错误示例,先别复制!):

💔 残酷的真相:数据为什么不更新?

运行一下,你会发现一个让人抓狂的现象:无论你怎么切换排序方式,数据都不会更新!
原理揭示:
React Query 是个“外卖配送员”,queryKey 就是你的送餐地址。
  • 你第一次点餐,地址是 ['repos']
  • 你切换排序,想要新餐,但你的地址依旧是 ['repos']
  • 外卖小哥(React Query)一看:“这个地址我已经送过了,缓存里有!他们肯定还在吃呢。” 于是他根本不去取新餐。
React Query 不会因为组件重新渲染就重新获取数据——这是特性,不是 bug!它的核心逻辑是:queryKey 不变,数据不变(在有效期内)。

🔑 解决方案:让 queryKey 动起来

解决办法其实很简单——把变化的参数放进 queryKey
✅ 黄金法则:如果某个值在 queryFn 里用到了,就必须放进 queryKey 里。
现在:
  1. 切换到 sort='updated' 时,queryKey 变成 ['repos', { sort: 'updated' }],这是一个新地址!React Query 立即触发请求。
  1. 切换回 sort='created' 时,queryKey 变回 ['repos', { sort: 'created' }]如果缓存存在,秒出!

🧠 深入原理:缓存的魔法

React Query 的缓存就像一个超级智能的储物柜系统,它通过 queryKey 来映射和区分数据:
当你切换回一个已缓存queryKey 时,数据会立即可用,UI 瞬间切换,不会出现 pending 状态(除非缓存过期)。这才是缓存的真正价值!

🤔 "这不就是 useEffect 的依赖数组吗?"

好问题!但 queryKeyuseEffect 的依赖数组友善多了:
特性
useEffect 依赖数组
queryKey 数组
比较方式
严格比较(引用变化即变化)
智能哈希(比较内容)
痛点
外部对象、数组引用变化易导致无限循环
塞入对象或数组是安全且推荐的做法
React Query 会比较 queryKey 的内容,而不是引用。 所以你可以放心地往里面塞对象和数组,不用担心引用变化的问题。

🛠️ 防呆神器:ESLint 插件

人非圣贤,孰能无忘?React Query 贴心地提供了 ESLint 插件,帮你检查是否漏了依赖:
配置好后,如果你忘了把 sort 加到 queryKey 里,ESLint 会温柔地提醒你:
ESLint: 您的 queryKey 中缺少以下依赖:sort
(@tanstack/query/exhaustive-deps)
就像 IDE 里的那个唠叨但负责的同事,虽然有时烦人,但真的能救你一命。

📦 课堂总结

  1. queryKey 不只是个标识符,它是触发重新获取的关键。
  1. 黄金法则:queryFn 用到啥,queryKey 就得有啥。
  1. 每个 queryKey 对应一个独立的缓存空间。
  1. queryKeyuseEffect 的依赖数组聪明——它比较内容,不是引用。
  1. 用 ESLint 插件防止自己犯傻。
记住,React Query 的 queryKey 就像是智能外卖系统的送餐地址——地址不变,它就认为你不需要新餐;地址变了,它立刻给你送新的。
下次当你的数据不更新时,别慌,先检查你的 queryKey 是不是忘了"报告"参数变化。毕竟,React Query 不是读心术大师,它需要你明确告诉它:"嘿,情况变了,该重新拿数据了!"

© 拾光 2025 - 2026

粤ICP备2025472574号