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

Redux Toolkit Query:如何用useLazyQuery实现多组件数据共享?

问题

我正在学习Redux Toolkit Query的查询结构,目前已经实现通过useMutation的fixedCacheKey在多组件间共享数据,无需借助Reducer存储;但使用useLazyQuery时,需要额外通过dispatch将数据存入Reducer。想请教是否存在类似fixedCacheKey的方案,实现多组件通过useLazyQuery共享数据,避免冗余的Reducer存储操作?

相关代码示例

CRUD文件

export const PromoService = apiClient.injectEndpoints({
    endpoints: (build) => ({
        fetchPromoById: build.query<
            Promotion,
            { ppeType: PpeType; id: string }
        >({
            query: ({ ppeType, id }) => apiQuery(ppeType, 'fetchPromoById', id),
            providesTags: (_result, _err) => [{ type: 'Promo' }],
        }),

        fetchPromoByCategory: build.mutation<
            PromotionData,
            { ppeType: PpeType; type: string; bannerId: string }
        >({
            query: ({ ppeType, type, bannerId }) => ({
                url: apiQuery(ppeType, 'fetchPromoByCategory'),
                method: 'POST',
                body: fetchPromoByCategoryBody(type, bannerId),
            }),
            invalidatesTags: ['Promo'],
        }),
    }),
});

export const { useLazyFetchPromoByIdQuery, useFetchPromoByCategoryMutation } =
    PromoService;

Slice文件

const initialState: PromotionState = {
    chosenPromotion: {} as Promotion,
    promoList: [],
};

const promoSlice = createSlice({
    name: 'promo',
    initialState,
    reducers: {
        setChosenPromotion: (state, action: PayloadAction<Promotion>) => {
            state.chosenPromotion = action.payload;
        },
        setPromoList: (state, action: PayloadAction<Promotion[]>) => {
            state.promoList = action.payload;
        },
    },
});

组件代码

const [fetchPromoByCategory, { isLoading, data: categoryData }] =
    useFetchPromoByCategoryMutation({
        fixedCacheKey: 'shared-update-promo',
    });

const [trigger, result] = useLazyFetchPromoByIdQuery();
const chosenPromo = result.data;

useEffect(() => {
    chosenPromo && dispatch(setChosenPromotion(chosenPromo));
}, [chosenPromo]);
解决方案

核心结论

useLazyQuery 同样支持 fixedCacheKey 参数,完全可以实现跨组件共享数据,无需额外将数据存入Reducer。

具体实现步骤

  1. 给useLazyQuery添加fixedCacheKey
    修改组件中useLazyFetchPromoByIdQuery的调用,传入fixedCacheKey选项,强制使用固定的缓存键存储数据:
// 第一个参数传undefined,表示初始不触发查询
const [trigger, result] = useLazyFetchPromoByIdQuery(undefined, {
  fixedCacheKey: 'shared-promo-by-id'
});
const chosenPromo = result.data;
  1. 跨组件共享缓存
    其他组件只要使用相同的fixedCacheKey调用useLazyFetchPromoByIdQuery,就能直接读取到已缓存的数据,不需要重复发起请求,也无需通过dispatch将数据存入Reducer:
// 另一个组件中
const [trigger, result] = useLazyFetchPromoByIdQuery(undefined, {
  fixedCacheKey: 'shared-promo-by-id'
});
// 直接使用result.data即可获取共享的缓存数据
const sharedPromo = result.data;
  1. 缓存更新与同步
  • 当需要更新数据时,在任意组件调用trigger方法发起新请求,RTK Query会自动更新缓存,所有使用该fixedCacheKey的组件都会同步拿到最新数据。
  • 如果需要让缓存失效,可以通过invalidatesTags配置(如你的fetchPromoByCategory mutation已经配置了invalidatesTags: ['Promo']),触发后相关缓存会被标记为失效,下次访问时会重新发起请求。

原理说明

RTK Query的缓存默认由查询名称+请求参数生成唯一的查询键(queryKey)。使用fixedCacheKey后,会强制用你指定的字符串作为查询键,忽略请求参数,因此所有使用同一个fixedCacheKey的组件都会共享同一份缓存数据,完全不需要额外的Reducer存储逻辑。

优化后的组件代码

可以直接删除原来的useEffect和Reducer存储逻辑,简化为:

const [fetchPromoByCategory, { isLoading, data: categoryData }] =
    useFetchPromoByCategoryMutation({
        fixedCacheKey: 'shared-update-promo',
    });

const [trigger, result] = useLazyFetchPromoByIdQuery(undefined, {
  fixedCacheKey: 'shared-promo-by-id'
});
const chosenPromo = result.data;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:15:34