如何访问指定RTK Query端点数据并在prepareHeaders中调用
RTK Query 访问跨API缓存与最新端点数据解决方案
一、在其他API中获取configurationApi的配置数据
RTK Query 所有端点的缓存数据都存储在对应reducerPath的Store状态中,每个端点内置官方生成的选择器,可以直接读取缓存数据,无需手动拼接缓存Key。
1. 动态注入请求头参数
你可以直接在prepareHeaders中通过configurationApi的内置选择器读取配置:
export const testApi = createApi({ reducerPath: "test", baseQuery: fetchBaseQuery({ baseUrl: "/api", prepareHeaders: (headers, { getState }) => { const state = getState() as RootState; // 传入调用loadConfiguration时的参数(无参数则传undefined),获取对应缓存数据 const config = configurationApi.endpoints.loadConfiguration.select(undefined)(state)?.data; if (config?.language) { headers.set('Accept-Language', config.language); } return headers; }, }), // 其他配置... });
2. 动态设置baseUrl
fetchBaseQuery的baseUrl是静态配置,要实现动态读取配置中的baseUrl,需要自定义一层baseQuery包装逻辑:
import type { BaseQueryFn, FetchArgs, FetchBaseQueryError } from '@reduxjs/toolkit/query/react'; const dynamicBaseQuery: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (args, api, extraOptions) => { const state = api.getState() as RootState; const config = configurationApi.endpoints.loadConfiguration.select(undefined)(state)?.data; // 可配置兜底地址,防止配置未加载完成时报错 const baseUrl = config?.baseUrl || '/fallback-api'; const rawBaseQuery = fetchBaseQuery({ baseUrl }); return rawBaseQuery(args, api, extraOptions); }; // testApi直接使用自定义的动态baseQuery export const testApi = createApi({ reducerPath: "test", baseQuery: dynamicBaseQuery, // 其他配置... });
注意:请确保配置请求优先于业务请求完成,可在应用根组件调用
useLoadConfigurationQuery,等配置返回后再渲染业务路由,避免读取到空配置。
二、获取指定端点的最新返回数据
每个query缓存条目都带有fulfilledTimeStamp字段(请求完成的时间戳),遍历指定端点的所有缓存条目,按时间戳降序排序后取第一条即可得到最近一次返回的结果:
import { createSelector } from '@reduxjs/toolkit'; // 定义获取最新loadUser数据的选择器 const selectLatestLoadUser = createSelector( (state: RootState) => state[userApi.reducerPath].queries, (allQueries) => { // 过滤出所有loadUser端点的缓存条目 const loadUserEntries = Object.values(allQueries).filter( entry => entry?.endpointName === 'loadUser' && entry.status === 'fulfilled' ); if (loadUserEntries.length === 0) return undefined; // 按完成时间降序排序,取最新的一条数据 return loadUserEntries.sort((a, b) => (b.fulfilledTimeStamp || 0) - (a.fulfilledTimeStamp || 0))[0].data; } ); // 使用示例:在组件/prepareHeaders等能获取state的地方调用 const latestUser = selectLatestLoadUser(getState());
提示:可通过
keepUnusedDataFor配置端点的缓存过期时间,自动清理无用缓存,避免遍历过多无效条目。
内容的提问来源于stack exchange,提问作者Chris Panayotoff
相关产品推荐
相关产品推荐

