I am having trouble combining my custom middleware with the default middlewares in my store configuration when using redux persist and rtk query

Here is the content of my store.ts file:

import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web
import {
  FLUSH,
  PAUSE,
  PERSIST,
  persistReducer,
  persistStore,
  PURGE,
  REGISTER,
  REHYDRATE
} from 'redux-persist';
import { combineReducers } from 'redux';
import { configureStore, createAsyncThunk } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query';
import { authApi } from './services/authApi';
import adminReducer from './slices/adminSlice';
import { categoryApi } from './services/categoryApi';
import { PersistPartial } from 'redux-persist/es/persistReducer';

// Setting up a persist config
const persistConfig = {
  key: 'root',
  storage, // Using localStorage as the default storage
  whitelist: ['admin'] // Defining slices to be persisted (e.g., 'admin')
};

// Combining reducers
const rootReducer = combineReducers({
  [authApi.reducerPath]: authApi.reducer,
  [categoryApi.reducerPath]: categoryApi.reducer,
  admin: adminReducer
});

// Applying persistence to the root reducer
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = configureStore({
  reducer: persistedReducer,

  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false
    }).concat([categoryApi.middleware, authApi.middleware]), // Merging both middlewares

  devTools: true
});

// Enabling refetching on focus/refocus (optional but recommended)
setupListeners(store.dispatch);

export const persistor = persistStore(store);

// Enabling refetching on focus/refocus (optional but recommended)
setupListeners(store.dispatch);

// Store types definition
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

Content of categoryApi.ts:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { Category } from 'src/models/category_type';

export const categoryApi = createApi({
  reducerPath: 'category',
  baseQuery: fetchBaseQuery({ baseUrl: 'base_url' }),
  endpoints: (builder) => ({
    getCategories: builder.query<{categories: Category[]}, void>({
      query: () => '/categories'
    })
  })
});

export const {
  useGetCategoriesQuery
} = categoryApi;

The structure of categoryApi is similar to authApi mentioned earlier.

I am facing difficulty in resolving an error and have tried several solutions without success.

Both authApi and categoryApi are created using createApi and fetchBaseQuery functions.

I attempted to merge rtk middleware authApi.middleware and categoryApi.middleware with default middleware and encountered type mismatch errors.

Please help me as I am feeling exhausted, and thank you in advance.

Answer №1

To optimize code structure, it is advisable to consolidate api endpoints in a single apiSlice if categoryApi and authApi share the same "baseQuery". For detailed instructions, refer to the documentation here

If separate API slices are necessary, you can follow this approach:

middleware: (getDefaultMiddleware) => getDefaultMiddleware()
     .concat(authApi.middleware)
     .concat(categoryApi.middleware)

Answer №2

After reviewing the code comments regarding adding middlewares, it appears that the code may not be functioning as intended.

export const store = configureStore({
  reducer: persistedReducer,

  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false
    }).concat([categoryApi.middleware, authApi.middleware]), // Concatenate both middlewares

  devTools: true
});

It's important to note that you are actually concatenating an array of two middlewares rather than just two separate middlewares. It is recommended to pass the middlewares directly for clarity and proper functionality.

Here's an example:

export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false
    })
      .concat(
        categoryApi.middleware,
        authApi.middleware
      ),
  devTools: true
});

For more comprehensive information on using getDefaultMiddleware and Typescript, refer to the Official Documentation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Typescript raises an issue regarding a React component's optional prop potentially being undefined

I have a basic React component that looks like this: interface ComponentProperties { onClick?: () => void; } const CustomComponent = (properties: ComponentProperties) => { if (!properties.onClick) { return <></>; } ...

Can a specific type be created for a nested object that has varying levels of depth?

One of my functions organizes objects based on the length of an input array. For example: fn(['a']) -> Record<string, string> fn(['a', 'b']) -> Record<Record<string, string>> I've defined the ret ...

I'm having trouble managing state properly in Safari because of issues with the useState hook

Encountering Safari compatibility issues when updating a component's state. Though aware of Safari's stricter mode compared to Chrome, the bug persists. The problem arises with the inputs: https://i.sstatic.net/WSOJr.png Whenever an option is ...

Creating an Angular service that checks if data is available in local storage before calling an API method can be achieved by implementing a

I am currently working on developing an Angular service that can seamlessly switch between making actual API calls and utilizing local storage within a single method invocation. component.ts this.userService.getAllUsers().subscribe(data => { conso ...

What is the source of the compiler options in tsconfig.json?

Currently utilizing Typescript in NestJs, I have incorporated various packages. However, the specific package responsible for altering these settings remains unknown to me: "checkJs": false, "skipLibCheck": true Is there a method to ...

Create a Typescript generic function that can return a variety of data types including strings, numbers, and

I have a function written in Typescript and I am looking to determine the return type based on the value retrieved from process.env. For instance, the variables in my Node process.env can be strings, numbers, or booleans. I want to fetch them with their s ...

Evolution of ReactJS state over time

When working with React, I wanted to increment a state variable called progressValue by 0.1 every 500 ms until it reaches 100. Here's what I initially tried: const [progressValue, setProgressValue] = React.useState<number>(0) const tick ...

Error: The specified attribute "property" is not valid for the type "IntrinsicAttributes"

I am currently new to the world of React with Typescript and I am trying to learn how to create a Bar chart using Chart.js within a React Typescript App. My goal is to pass the value of the property datasets as a prop to the BarChart.tsx component. Below ...

The most suitable TypeScript type for a screen being utilized again in react-navigation v5

When it comes to typing screens under react-navigation v5, I usually follow a simple pattern: // Params definition type RouteParamsList = { Screen1: { paramA: number } Screen2: undefined } // Screen1 type Props = StackScreenProps<R ...

Encountering an issue of Property not existing on JSX intrinsic elements when utilizing TSS with Javascript (without TypeScript)

I am currently working on a JavaScript project (using create-react-app 2.0) and utilizing tsserver without Typescript. I encountered a linting error that states: Property 'svg-icon' does not exist on type 'JSX.intrinsictElements'. Thi ...

The functionality of Layout.tsx is inconsistent across various pages

I'm having trouble with the console.log() code to display the page path only showing up in the "pages.tsx" file (src/app/pages.tsx) and not appearing in the console for other files located in (src/page/Login). Here is the code from layout.tsx: ' ...

What is the proper way to implement jest.mock in a describe or it block?

Using typescript and jest, I am faced with a scenario involving two files: users.service.ts, which imports producer.ts. In an attempt to mock a function in producer.ts, I successfully implement it. import { sendUserData } from "./users.service"; const pro ...

Eliminate properties from a TypeScript interface object

After receiving a JSON response and storing it in MongoDB, I noticed that unnecessary fields are also being stored in the database. Is there a way to remove these unnecessary fields? interface Test{ name:string }; const temp :Test = JSON.parse('{ ...

Accessing objects using string literals is restricted! I am encountering an issue while attempting to access the route parameter 'id' via a dynamic ID

Let's take a look at my custom [app-routing.modulse.ts] module: const appRoutes: Routes = [ { path: '', redirectTo: '/recipes', pathMatch: 'full' }, { path: 'recipes', component: RecipesComponent, child ...

Interactive 3D model movable within designated area | R3F

I am currently facing a challenge in limiting the drag area of my 3D models to the floor within my FinalRoom.glb model. After converting it to tsx using gltfjsx, I obtained the following code: import * as THREE from "three"; import React, { useRe ...

The Ionic project compilation was unsuccessful

Issue: This module is defined using 'export =', and can only be utilized with a default import if the 'allowSyntheticDefaultImports' flag is enabled. Error found in the file: 1 import FormData from "form-data"; ~~~~~~~~ node ...

Tips for attaching an event listener to a div element that is accessed by reference in a React and TypeScript environment

I am attempting to attach an event listener to the div element using a ref. In my code, I have added a ref called div_ref to the Wrapper div and accessed that div_ref in the enableDragEventListeners method to add event listeners to it on component mount. ...

Error TS2339 occurs when the property "classes" is not found in the type "PropsWithChildren"

I have encountered a typescript error while transitioning our files to typescript. As a newcomer to typescript, it has been quite challenging for me to search for solutions online. My approach is to grasp the error first before delving into finding a resol ...

Having trouble importing SVG as a React component in Next.js

I initially developed a project using create-react-app with Typescript, but later I was tasked with integrating next.js into it. Unfortunately, this caused some SVGs throughout the application to break. To resolve this issue, I implemented the following pa ...

Accessing the ViewModel property of a parent component from the ViewModel of its child in Aurelia

Having a scenario with two distinct components: <parent-component type="permanent"> <div child-component></div> </parent-component> class ParentComponentCustomElement { @bindable public type: string = "permanent"; } clas ...