如何避免使用Redux Toolkit (RTK) 时重复获取数据?
解决RTK Query组件挂载时重复请求的问题
RTK Query默认自带缓存机制,你可以通过以下几种方式避免组件重复挂载时的无效请求:
1. 调整缓存保留时长
RTK Query默认会在数据不再被组件使用(卸载后)保留5分钟,你可以全局或针对单个接口延长这个时间,确保缓存不会提前失效:
修改你的postsApi配置:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const postsApi = createApi({ reducerPath: "postsApi", baseQuery: fetchBaseQuery({ baseUrl: "https://jsonplaceholder.typicode.com/", }), // 全局设置未使用数据保留时长(单位:秒),示例为24小时 keepUnusedDataFor: 86400, endpoints: (builder) => ({ posts: builder.query({ query: () => "/posts", // 也可以单独给这个接口设置缓存时长,覆盖全局配置 // keepUnusedDataFor: 43200 // 12小时 }), }), }); export const { usePostsQuery } = postsApi;
2. 通过skip参数手动跳过请求
在组件中检查是否已有缓存数据,若存在则跳过新请求:
修改Home组件的请求逻辑:
const Home = () => { // 从store读取已缓存的数据 const cachedPosts = useSelector( (state) => state?.postsApi?.queries?.["posts(undefined)"]?.data ); // 当缓存存在时,跳过请求 const { data, error, isLoading, isFetching, isSuccess } = usePostsQuery(undefined, { skip: !!cachedPosts }); return ( <> {isSuccess && console.log("data", data)} </> ); }; export default Home;
3. 使用useLazyQuery手动触发请求
如果希望完全控制请求时机,改用useLazyQuery,仅在没有缓存时发起请求:
组件代码调整:
import { useLazyQuery } from "@reduxjs/toolkit/query/react"; import { postsApi } from "./services/postsApi"; import { useSelector, useEffect } from "react"; const Home = () => { const cachedPosts = useSelector( (state) => state?.postsApi?.queries?.["posts(undefined)"]?.data ); // 初始化懒加载请求函数 const [fetchPosts, { data, error, isLoading }] = useLazyQuery(postsApi.endpoints.posts); useEffect(() => { // 仅当无缓存时触发请求 if (!cachedPosts) { fetchPosts(); } }, [cachedPosts, fetchPosts]); return ( <> {data && console.log("data", data)} </> ); }; export default Home;
原理说明
RTK Query的缓存基于查询键(query key),你的posts接口无参数,键为posts(undefined)。只要缓存未过期且未被清理,组件挂载时会直接读取缓存而非发起新请求。上述方案分别从缓存有效期、请求触发条件、请求时机三个维度解决重复请求问题,可根据实际需求选择。
内容的提问来源于stack exchange,提问作者someone
相关产品推荐
相关产品推荐

