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 里。现在:
- 切换到
sort='updated'时,queryKey变成['repos', { sort: 'updated' }],这是一个新地址!React Query 立即触发请求。
- 切换回
sort='created'时,queryKey变回['repos', { sort: 'created' }],如果缓存存在,秒出!
🧠 深入原理:缓存的魔法
React Query 的缓存就像一个超级智能的储物柜系统,它通过
queryKey 来映射和区分数据:当你切换回一个已缓存的
queryKey 时,数据会立即可用,UI 瞬间切换,不会出现 pending 状态(除非缓存过期)。这才是缓存的真正价值!🤔 "这不就是 useEffect 的依赖数组吗?"
好问题!但
queryKey 比 useEffect 的依赖数组友善多了:特性 | useEffect 依赖数组 | queryKey 数组 |
比较方式 | 严格比较(引用变化即变化) | 智能哈希(比较内容) |
痛点 | 外部对象、数组引用变化易导致无限循环 | 塞入对象或数组是安全且推荐的做法 |
React Query 会比较
queryKey 的内容,而不是引用。 所以你可以放心地往里面塞对象和数组,不用担心引用变化的问题。🛠️ 防呆神器:ESLint 插件
人非圣贤,孰能无忘?React Query 贴心地提供了 ESLint 插件,帮你检查是否漏了依赖:
配置好后,如果你忘了把
sort 加到 queryKey 里,ESLint 会温柔地提醒你:ESLint: 您的 queryKey 中缺少以下依赖:sort(@tanstack/query/exhaustive-deps)
就像 IDE 里的那个唠叨但负责的同事,虽然有时烦人,但真的能救你一命。
📦 课堂总结
- queryKey 不只是个标识符,它是触发重新获取的关键。
- 黄金法则:
queryFn用到啥,queryKey就得有啥。
- 每个
queryKey对应一个独立的缓存空间。
queryKey比useEffect的依赖数组聪明——它比较内容,不是引用。
- 用 ESLint 插件防止自己犯傻。
记住,React Query 的
queryKey 就像是智能外卖系统的送餐地址——地址不变,它就认为你不需要新餐;地址变了,它立刻给你送新的。下次当你的数据不更新时,别慌,先检查你的
queryKey 是不是忘了"报告"参数变化。毕竟,React Query 不是读心术大师,它需要你明确告诉它:"嘿,情况变了,该重新拿数据了!"