RTK Query中selectId返回undefined错误排查求助
问题:RTK Query中selectId返回undefined报错
问题现象
从数据库获取30个用户数据时,控制台针对每个用户输出如下报错:
The entity passed to the
selectIdimplementation returned undefined. You should probably provide your ownselectIdimplementation. The entity that was passed
问题定位在getAllUsers请求(apiSlice.js第22行),且尝试过某解决方案无效。
相关代码
apiSlice.js
import { createSelector, createEntityAdapter } from "@reduxjs/toolkit"; import { apiSlice } from '../apiSlice'; const usersAdapter = createEntityAdapter() const initialState = usersAdapter.getInitialState() export const extendedApiSlice = apiSlice.injectEndpoints({ endpoints: (builder) => ({ getUsers: builder.query({ query: (pagination) => ({ url: `/user/pagination/${pagination}`, }), transformResponse: (response) => { return response; }, providesTags: (result, error, id) => [{ type: 'Post', id }], }), getAllUsers: builder.query({ query: () => '/user/all', transformResponse: (res) => { return usersAdapter.setAll(initialState, res) }, }), }), }); export const { useGetUsersQuery, useGetAllUsersQuery } = extendedApiSlice; export const selectUsersResult = extendedApiSlice.endpoints.getAllUsers.select() const selectUsersData = createSelector( selectUsersResult, (usersResult, selectId) => usersResult.data ) export const { selectAll: selectAllUsers, selectById: selectUserById, } = usersAdapter.getSelectors((state) => selectUsersData(state) ?? initialState)
index.jsx
import React from 'react'; import ReactDOM from 'react-dom/client'; import { App } from './app'; import { store } from './store/store'; import { extendedApiSlice } from './store/friends/friendsApi'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; const el = document.getElementById('root'); if (el === null) throw new Error('Root container missing in index.html'); store.dispatch(extendedApiSlice.endpoints.getAllUsers.initiate()); const root = ReactDOM.createRoot(el); root.render( <BrowserRouter> <Provider store={store}> <App /> </Provider> </BrowserRouter>, );
组件调用代码
const allUsers = useAppSelector(selectAllUsers); console.log(allUsers);
无效解决方案(翻译自截图)
尝试在createEntityAdapter中传入selectId配置,但未解决问题:
const usersAdapter = createEntityAdapter({ selectId: (user) => user.id })
问题分析与解决
selectId的来源
createEntityAdapter默认使用实体对象的id属性作为唯一标识(即默认逻辑为selectId: (entity) => entity.id)。若你的用户数据中没有id字段,或唯一标识字段名不是id(比如userId/user_id),就会导致selectId返回undefined,触发报错。
核心问题
- 用户数据的唯一标识字段与
createEntityAdapter默认规则不匹配; selectUsersData定义中多余了selectId参数,属于无效参数。
正确解决方案
1. 指定正确的selectId
根据用户数据实际的唯一标识字段,配置createEntityAdapter:
// 替换为你实际的唯一标识字段,比如userId或user_id const usersAdapter = createEntityAdapter({ selectId: (user) => user.userId })
2. 修正selectUsersData的定义
移除多余的selectId参数:
const selectUsersData = createSelector( selectUsersResult, (usersResult) => usersResult.data // 删除第二个参数selectId )
3. 优化transformResponse(可选)
无需每次传入固定的initialState,直接使用适配器的初始状态:
transformResponse: (res) => { return usersAdapter.setAll(usersAdapter.getInitialState(), res) }
验证
修改后重新请求数据,控制台报错会消失,selectAllUsers可正确返回用户列表。
内容的提问来源于stack exchange,提问作者bi zi
相关产品推荐
相关产品推荐

