You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux-Toolkit RTK-Query测试报错:injectEndpoints读取undefined

解决RTK-Query中TypeError: Cannot read property 'injectEndpoints' of undefined错误

问题场景

使用Redux-Toolkit的RTK-Query运行测试时,触发TypeError: Cannot read property 'injectEndpoints' of undefined错误。

根因

模块循环导入导致初始化顺序异常:

  • api文件中导入了authSlice的logout动作
  • authSlice又导入了通过api.injectEndpoints创建的authApi,用于编写extraReducers的匹配器
    模块加载时api尚未完成初始化,就被authSlice引用,导致调用injectEndpoints时api为undefined。

解决方案

方案1:拆分独立的action文件,切断循环依赖

把auth相关的基础action抽离到独立文件,让api和authSlice都导入这个文件,避免互相引用:

  1. 创建authActions.js:
import { createAction } from '@reduxjs/toolkit';
export const logout = createAction('auth/logout');
export const setUser = createAction('auth/setUser');
  1. 修改authSlice.js:
import { createSlice } from '@reduxjs/toolkit';
import { logout, setUser } from './authActions';

const authSlice = createSlice({
  name: 'auth',
  initialState: { user: null },
  extraReducers: (builder) => {
    builder.addCase(logout, (state) => {
      state.user = null;
    });
    builder.addCase(setUser, (state, action) => {
      state.user = action.payload;
    });
    // 用字符串匹配器替代导入authApi,彻底避免循环
    builder.addMatcher(
      (action) => action.type.endsWith('/login/fulfilled'),
      (state, action) => {
        state.user = action.payload;
      }
    );
  }
});

export default authSlice.reducer;
  1. 修改api.js:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { logout } from './authActions';

const baseApi = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  endpoints: () => ({})
});

// 注入auth相关端点
export const api = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    login: builder.query({
      query: (credentials) => ({
        url: '/login',
        method: 'POST',
        body: credentials
      }),
      // 如需触发logout,直接使用导入的action
      onQueryStarted: async (args, { dispatch }) => {
        // dispatch(logout());
      }
    })
  })
});

export const { useLoginQuery } = api;

方案2:将状态更新逻辑移至RTK-Query生命周期

如果不需要在authSlice中监听authApi的端点状态,可以把状态更新逻辑移到RTK-Query的onQueryStarted中,避免authSlice依赖authApi:

// api.js
import { setUser } from './authActions';

export const api = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    login: builder.query({
      query: (credentials) => ({ /* ... */ }),
      onQueryStarted: async (args, { dispatch, queryFulfilled }) => {
        const { data } = await queryFulfilled;
        // 直接dispatch更新auth状态的action
        dispatch(setUser(data.user));
      }
    })
  })
});

测试配置注意事项

测试时确保store配置正确,避免重复初始化或循环导入:

// 测试用store配置
import { configureStore } from '@reduxjs/toolkit';
import { api } from './api';
import authReducer from './authSlice';

export const setupTestStore = () => {
  return configureStore({
    reducer: {
      [api.reducerPath]: api.reducer,
      auth: authReducer
    },
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware().concat(api.middleware)
  });
};

内容的提问来源于stack exchange,提问作者Karine Hiulumian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 07:05:52