开发者问题收集

RTK 查询 extraReducers:未捕获 TypeError:无法读取未定义的属性(读取“matchFulfilled”)

2023-03-23
1031

我使用 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;
2个回答

如果您在此处访问 baseApi.endpoints.registerUser.matchFulfilled ,则无法保证 registerUser 端点在当时已被注入(这意味着:注入它的文件已被包含)。

改为导出 authApi ,并使用 authApi.endpoints.registerUser.matchFulfilled

authApibaseApi 是同一个对象(从字面上看,是对同一个对象的引用!),但在 authApi 可用时,您可以保证已对 registerUser 进行了 injectEndpoints 调用。

phry
2023-03-23

如果您使用 @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-查询/使用/代码生成

Nipun Ravisara
2024-01-22