RTK 查询 extraReducers:未捕获 TypeError:无法读取未定义的属性(读取“matchFulfilled”)
我使用 RTK 和 RTK Query 在我的应用中进行状态管理和数据提取。我的商店是通过代码拆分设置的,在初始加载应用时,我收到与
storeNew/authSliceNew.js
中定义的
extraReducer
相关的以下错误
Uncaught TypeError:无法读取未定义的属性“matchFulfilled”
到目前为止,我意识到如果我在
storeNew/authSliceNew.js
中注释掉我的
extraReducers
,重新加载应用,然后取消注释它们,它们似乎可以正常工作。但如果我从一开始就取消注释它们,我就会收到错误。到目前为止,我尝试寻找解决方案几个小时,但找不到任何有用的方法。因此,如果有人能为我指明正确的方向,我将非常高兴。
我的
storeNew/baseApi.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const baseApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: "api/" }),
endpoints: () => ({}),
tagTypes: ["User", "Budget"],
});
我的
storeNew/authApiNew.js
import { baseApi } from "./baseApi";
const authApi = baseApi.injectEndpoints({
endpoints: (builder) => ({
registerUser: builder.mutation({
query: (registerCredentials) => ({
url: "account/register",
method: "POST",
body: { ...registerCredentials },
}),
}),
}),
overrideExisting: false,
});
export const {
useRegisterUserMutation,
} = authApi;
我的
storeNew/authSliceNew.js
import { createSlice } from "@reduxjs/toolkit";
import { baseApi } from "./baseApi";
const initialState = {
isAuthenticated: false,
register_success: false,
feedback: null,
feedbackType: null,
};
const authSlice = createSlice({
name: "auth",
initialState: initialState,
reducers: {
resetFeedback: (state) => {
state.feedback = null;
state.feedbackType = null;
},
resetRegisterSuccess: (state) => {
state.register_success = false;
},
},
extraReducers: (builder) => {
builder.addMatcher(
baseApi.endpoints.registerUser.matchFulfilled,
(state) => {
state.register_success = true;
state.feedback = null;
state.feedbackType = null;
}
);
},
});
export const authActions = authSlice.actions;
export default authSlice;
我的
storeNew/index.js
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { baseApi } from "./baseApi";
import authSliceNew from "./authSliceNew";
const store = configureStore({
reducer: {
[baseApi.reducerPath]: baseApi.reducer,
authNew: authSliceNew.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(baseApi.middleware),
});
setupListeners(store.dispatch);
export default store;
如果您在此处访问
baseApi.endpoints.registerUser.matchFulfilled
,则无法保证
registerUser
端点在当时已被注入(这意味着:注入它的文件已被包含)。
改为导出
authApi
,并使用
authApi.endpoints.registerUser.matchFulfilled
。
authApi
与
baseApi
是同一个对象(从字面上看,是对同一个对象的引用!),但在
authApi
可用时,您可以保证已对
registerUser
进行了
injectEndpoints
调用。
如果您使用
@rtk-query/codegen-openapi
来生成端点,则需要进行一些小的配置调整。
将
exportName
添加到您的配置文件。这会将端点注入的 baseApi 实例导出为您提供的导出名称。
config.ts
import type { ConfigFile } from "@rtk-query/codegen-openapi";
const config: ConfigFile = {
schemaFile: "PATH_TO_SCHEMA"
apiFile: "../utils/clients/baseApi.ts", // base API instance
apiImport: "baseApi",
exportName: "clientEndpoints",
hooks: true,
outputFiles: {
"../services/user.ts": {
filterEndpoints: [/user/i],
},
"../services/auth.ts": {
filterEndpoints: [/auth/i],
},
... //other outputFile patterns
},
};
export default config;
生成的端点将导出 injectionRtkApi 作为 clientEndpoints
auth.generated.ts
export { injectedRtkApi as clientEndpoints };
在您的
extraReducers
authSlice.ts
import { clientEndpoints } from "@/services/auth";
const authSlice = createSlice({
name: "auth",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addMatcher(
clientEndpoints.endpoints.login.matchFulfilled,
(state, action) => {
console.log("fulfilled", action);
const stateCopy = state;
stateCopy.userId = action?.payload?.user?.id;
stateCopy.accessToken = action?.payload?.token;
}
);
},
});
ref: rtk-查询/使用/代码生成