You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用useQuery实现数据筛选时onChange触发refetch更新异常问题

问题原因

React的状态更新是异步批量执行的,调用setFilterGenre/setFilterText后,当前执行上下文内的filterGenre/filterText仍然是更新前的旧值,此时立刻调用query.refetch(),请求携带的就是上一次的筛选参数,和你遇到的现象完全吻合:

  • 第一次点击comedy时,refetch用的还是初始空值,和之前的查询参数一致,react-query默认复用缓存不会发起新请求,后续状态才更新为comedy
  • 第二次点击Drama时,refetch用的是已经更新完成的comedy值,所以请求参数为?genres=comedy,后续状态才更新为Drama
    同时你当前的用法不符合react-query的设计规范,额外用useState存储接口返回的shows数据,还存在状态不同步的隐患。

解决方案

按照react-query的设计逻辑修改代码,将筛选参数加入查询key,参数变化时react-query会自动发起新请求,无需手动调用refetch:

1. 修改查询逻辑

const [genres, setGenres] = useState([]);
const [filterGenre, setFilterGenre] = useState("");
const [filterText, setFilterText] = useState("");

// 将筛选参数加入query key数组,参数变化自动触发重新查询
const query = useQuery(["show-page", filterGenre, filterText], () => api.search(filterGenre, filterText));

const queryGenre = useQuery("genres", api.genres, {
  onSuccess: (data) => setGenres(Object.keys(data.data.genres)),
});

// 仅需更新筛选状态,无需手动调用refetch
const handleSelect = (e) => {
  setFilterGenre(e.target.value);
};

const handleInput = (e) => {
  setFilterText(e.target.value);
};

2. 修改渲染逻辑

移除多余的shows状态,直接使用react-query返回的查询数据,同时将下拉框和输入框改为受控组件,避免状态和显示不一致:

<>
  {query.isLoading && <Spinner />}
  {query.isSuccess && (
    <>
      <select name="genre" onChange={handleSelect} value={filterGenre}>
        <option value="">All</option>
        {genres.map((genre) => {
          return <option key={genre} value={genre}>{genre}</option>;
        })}
      </select>

      <input 
        type="text" 
        onChange={handleInput} 
        value={filterText}
      />

      <div className="container-show-page">
        {query.data.data.shows.map((show) => {
          return (
            <div key={show.id} className="card-show-page">
              <img src={show.poster} alt={show.name} className="image-show-page" />
            </div>
          );
        })}
      </div>
    </>
  )}
</>

内容的提问来源于stack exchange,提问作者jeyremd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:48:01