React Query V3:手动触发refetch如何复用缓存数据?
React Query V3 实现refetch复用缓存方案
React Query中refetch方法默认会强制发起新请求(force: true),这就是你每次调用都会触发API请求的原因。要实现已有缓存时复用缓存、仅在缓存过期/不存在时发起请求,可通过以下两种方式解决:
方案一:调用refetch时禁用强制请求
refetch支持传入配置参数,将force设为false后,React Query会先检查缓存是否处于新鲜状态,若新鲜则直接复用缓存,不会发起新请求。
步骤:
- 给
useQuery设置合理的staleTime(缓存新鲜时长,默认0,即缓存立刻过期) - 调用
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
相关产品推荐
相关产品推荐

