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

