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

React点击按钮手动刷新react-query时如何展示Loading而非Updating状态

问题原因

react-query 的status === 'loading'状态仅会在首次查询、无任何缓存数据时触发。当已经有缓存数据后,触发重取操作时status会保持为success,仅通过isRefetching标记位标识正在重取,这就是你现在点击按钮只会显示Updating的原因。

解决方案

这里提供两种符合react-query使用规范的实现方式:

方案1:合并加载状态判断(保留旧数据展示)

如果希望重取时依然展示旧数据,同时把加载提示统一为Loading,直接修改渲染判断逻辑即可:

  • 删掉原有单独判断isRefetching显示Updating的代码
  • 给loading的判断逻辑增加isRefetching条件
    修改后的渲染部分代码如下:
return (
  <div className="Container">
    <button onClick={() => setValue(prevValue => prevValue + 1 )}>Set value</button>
    {status === 'error' && <div className="mt-5">{error.message}</div>}
    {/* 首次加载和重取都显示Loading */}
    {(status === 'loading' || isRefetching) && <div className="mt-5">Loading data ...</div>}
    {status === 'success' && !isRefetching && (
      <div>
        {result?.map((inner: any, index: number) => {
          return <li key={index}>{inner.title}</li>;
        })}
      </div>
    )}
  </div>
);

方案2:关联queryKey到依赖变量(重取时清空旧数据,进入原生loading状态)

这是更符合react-query设计思想的方案:queryKey本身就应该包含所有影响查询结果的变量,变量变更后react-query会自动识别为新查询,直接进入loading状态,不需要手动调用refetch。
修改点如下:

  1. 把固定的queryKey改为包含value的数组
  2. 删掉监听value变化调用refetch的useEffect逻辑
    修改后的核心代码如下:
const App: React.FunctionComponent = () => {
  const [value, setValue] = React.useState<number>(7);

  // queryKey包含依赖变量value
  const queryKey = ['getData', value];

  const getData = async (): Promise<any> => {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    const response = await axios
      .get(`https://jsonplaceholder.typicode.com/todos`)
      .then((res) => res.data);
    return response;
  };

  const {
    data: result,
    status,
    error,
  }: any = useQuery(queryKey, getData, {
    refetchOnWindowFocus: true,
    staleTime: 0,
    cacheTime: 0,
    refetchInterval: 0,
  });

  return (
    <div className="Container">
      <button onClick={() => setValue(prevValue => prevValue + 1 )}>Set value</button>
      {status === 'error' && <div className="mt-5">{error.message}</div>}
      {status === 'loading' && <div className="mt-5">Loading data ...</div>}
      {status === 'success' && (
        <div>
          {result?.map((inner: any, index: number) => {
            return <li key={index}>{inner.title}</li>;
          })}
        </div>
      )}
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:27:03