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

React Query V3:手动触发refetch如何复用缓存数据?

React Query V3 实现refetch复用缓存方案

React Query中refetch方法默认会强制发起新请求(force: true),这就是你每次调用都会触发API请求的原因。要实现已有缓存时复用缓存、仅在缓存过期/不存在时发起请求,可通过以下两种方式解决:

方案一:调用refetch时禁用强制请求

refetch支持传入配置参数,将force设为false后,React Query会先检查缓存是否处于新鲜状态,若新鲜则直接复用缓存,不会发起新请求。

步骤:

  1. 给useQuery设置合理的staleTime(缓存新鲜时长,默认0,即缓存立刻过期)
  2. 调用refetch时传入{ force: false }

修改后的代码示例:

import { useQuery } from 'react-query';
import axios from 'axios';

function Example() {
  const [x, setX] = useState(1);
  const { isLoading, error, data, isFetching, refetch } = useQuery(
    "repoData",
    () =>
      axios
        .get("https://api.github.com/repos/tannerlinsley/react-query")
        .then((res) => res.data),
    {
      staleTime: 5 * 60 * 1000, // 设置5分钟的缓存新鲜期
    }
  );

  useEffect(() => {
    // 仅当缓存过期/不存在时才发起请求
    refetch({ force: false });

    setTimeout(() => {
      setX((prevState) => prevState + 1);
    }, 5000);
  }, [x, refetch]);

  if (isLoading) return "Loading...";
  if (error) return "An error has occurred: " + error.message;

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{" "}
      <strong>✨ {data.stargazers_count}</strong>{" "}
      <strong>🍴 {data.forks_count}</strong>
      <div>{isFetching ? "Updating..." : ""}</div>
      <ReactQueryDevtools initialIsOpen />
    </div>
  );
}

方案二:手动检查缓存状态后决定是否调用refetch

通过useQueryClient获取查询的缓存状态,手动判断是否需要发起请求,适合更精细的缓存控制场景。

代码示例:

import { useQuery, useQueryClient } from 'react-query';
import axios from 'axios';

function Example() {
  const [x, setX] = useState(1);
  const queryClient = useQueryClient();
  const { isLoading, error, data, isFetching, refetch } = useQuery(
    "repoData",
    () =>
      axios
        .get("https://api.github.com/repos/tannerlinsley/react-query")
        .then((res) => res.data),
    {
      staleTime: 5 * 60 * 1000,
    }
  );

  useEffect(() => {
    const queryState = queryClient.getQueryState("repoData");
    // 仅在缓存不存在、加载中或已过期时调用refetch
    if (!queryState || queryState.state === 'loading' || queryState.isStale) {
      refetch();
    }

    setTimeout(() => {
      setX((prevState) => prevState + 1);
    }, 5000);
  }, [x, queryClient, refetch]);

  if (isLoading) return "Loading...";
  if (error) return "An error has occurred: " + error.message;

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{" "}
      <strong>✨ {data.stargazers_count}</strong>{" "}
      <strong>🍴 {data.forks_count}</strong>
      <div>{isFetching ? "Updating..." : ""}</div>
      <ReactQueryDevtools initialIsOpen />
    </div>
  );
}

关键说明:

  • staleTime是核心配置:它决定了缓存数据从"新鲜"变为"陈旧"的时长。新鲜状态下,React Query会直接复用缓存,不会发起请求。
  • 如果你的业务需求是永久复用缓存(除非主动失效),可以将staleTime设为Infinity,此时只要缓存存在,refetch({ force: false })就不会发起新请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:12:46