RTK Query:如何将userId注入slice的baseUrl处理路径变量?
解决方案
你的问题核心是RTK Query中无法在创建baseUrl时直接访问store状态——因为createApi是模块级别的初始化代码,执行时机早于store创建。下面提供两种可行方案,根据你的场景选择:
方案一:自定义动态BaseQuery(推荐,支持userId动态更新)
通过包装fetchBaseQuery,在每次请求时从store中获取最新的userId并拼接URL,完美适配userId可能变化的场景:
// mySlice.js import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // 基础baseQuery只保留共享前缀 const baseQuery = fetchBaseQuery({ baseUrl: '/common/path' }); // 自定义动态baseQuery,每次请求时注入userId const dynamicBaseQuery = async (args, api, extraOptions) => { // 从store根状态获取userId(根据你的实际state结构调整路径) const userId = api.getState().userId; // 处理请求参数,拼接userId和特定路径 let modifiedArgs = args; if (typeof args === 'string') { // 如果请求是字符串URL,直接拼接 modifiedArgs = `/${userId}/specific/path${args}`; } else if (args.url) { // 如果是对象形式的请求配置,修改url字段 modifiedArgs = { ...args, url: `/${userId}/specific/path${args.url}` }; } // 调用原baseQuery发起请求 return baseQuery(modifiedArgs, api, extraOptions); }; export const mySlice = createApi({ reducerPath: 'userSpecificApi', baseQuery: dynamicBaseQuery, endpoints: (builder) => ({ getTargetData: builder.query({ query: () => '/endpoints' // 最终URL会自动拼接为 /common/path/{userId}/specific/path/endpoints }), // 其他3个端点按同样方式定义 }) });
Store配置时,确保userId存在于根状态中:
// MyFile.jsx const initialUserId = '已获取的用户ID'; // 你的初始化userId const store = configureStore({ reducer: { [mySlice.reducerPath]: mySlice.reducer, // 用简单reducer保存userId(如果已有其他reducer管理userId,直接复用即可) userId: (state = initialUserId, action) => state }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(mySlice.middleware) });
方案二:工厂函数创建API(适合userId固定场景)
如果userId在初始化后不会变化,可以通过工厂函数传入userId,直接生成带固定baseUrl的API实例:
// mySlice.js import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; export const createUserSpecificApi = (userId) => { return createApi({ reducerPath: `userSpecificApi_${userId}`, // 避免多实例reducerPath冲突 baseQuery: fetchBaseQuery({ baseUrl: `/common/path/${userId}/specific/path` }), endpoints: (builder) => ({ getTargetData: builder.query({ query: () => '/endpoints' }), // 其他端点定义 }) }); };
Store配置时动态生成API:
// MyFile.jsx const userId = '已获取的用户ID'; const userSpecificApi = createUserSpecificApi(userId); const store = configureStore({ reducer: { [userSpecificApi.reducerPath]: userSpecificApi.reducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(userSpecificApi.middleware) });
为什么你的原写法无效?
createApi是在模块加载阶段执行的,此时store还未创建,自然无法访问state或getState。fetchBaseQuery的baseUrl参数是静态字符串,不能依赖运行时的store状态。
内容的提问来源于stack exchange,提问作者Lucy Johnston
相关产品推荐
相关产品推荐

