避免在RTK Query中通过属性透传查询参数
解决方案
针对你遇到的RTK Query缓存中获取唯一用户ID的问题,这里有几个直接高效的实现方式:
方法1:直接遍历缓存查询条目
因为你明确getUserQuery只会发起一次,直接从缓存的查询列表里提取数据或参数即可:
import { useSelector } from '@reduxjs/toolkit'; import { apiSlice } from './path/to/apiSlice'; // 获取用户对象 const user = useSelector(state => { const getUserQueries = apiSlice.endpoints.getUserQuery.select()(state).queries; // 取唯一的查询条目数据 return Object.values(getUserQueries)[0]?.data; }); const userId = user?.id; // 或者直接提取ID(不需要依赖返回数据) const userIdDirect = useSelector(state => { const getUserQueryKeys = Object.keys(apiSlice.endpoints.getUserQuery.select()(state).queries); if (!getUserQueryKeys.length) return null; // RTK Query的查询key是序列化后的参数数组,解析第一个参数就是用户ID return JSON.parse(getUserQueryKeys[0])[0]; });
方法2:自定义全局选择器
在你的apiSlice里提前封装好选择器,方便所有组件直接复用:
// apiSlice.js import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; export const apiSlice = createApi({ baseQuery: fetchBaseQuery({ baseUrl: '/api' }), tagTypes: ['User'], // 可选,用于缓存标签管理 endpoints: builder => ({ getUserQuery: builder.query({ query: (id) => `/users/${id}`, }), // 其他查询/ mutation 端点 }), }); // 封装获取当前用户ID的选择器 export const selectCurrentUserId = state => { const queryEntries = Object.entries(apiSlice.endpoints.getUserQuery.select()(state).queries); if (!queryEntries.length) return null; // 取第一个查询的参数ID const [queryKey] = queryEntries[0]; return JSON.parse(queryKey)[0]; }; // 封装获取当前用户对象的选择器 export const selectCurrentUser = state => { const queryEntries = Object.entries(apiSlice.endpoints.getUserQuery.select()(state).queries); if (!queryEntries.length) return null; const [, queryData] = queryEntries[0]; return queryData.data; };
之后在任意组件里直接使用:
import { useSelector } from '@reduxjs/toolkit'; import { selectCurrentUserId } from './apiSlice'; const userId = useSelector(selectCurrentUserId);
方法3:从标准化实体中提取(若启用数据标准化)
如果你的apiSlice配置了数据标准化(通过transformResponse或默认的标准化逻辑),可以直接从entities中取唯一用户:
const userId = useSelector(state => { const userEntities = apiSlice.selectEntities(state).User; return userEntities ? Object.keys(userEntities)[0] : null; });
这些方式都不需要通过UI层级传参或使用Context,直接利用RTK Query的缓存机制获取唯一的用户数据,完全适配你的场景。
内容的提问来源于stack exchange,提问作者PBrown
相关产品推荐
相关产品推荐

