I am trying to have all the slices in store so my app can access it, I saw similar issues on stackoverflow, they are suggesting to use a unique "reducerPath" name. But when I changed that I got another error caller
Warning: Middleware for RTK-Query API at reducerPath "apifb" has not been added to the store.
One more doubt, in store.js if there are more than 3 slices please suggest me a better way to concat them for middleware.
FacebookSlice
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "../../config/constants";
export const facebookSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: api.FACEBOOK_GRAPH_URL,
}),
endpoints: (builder) => ({
getPagePhotos: builder.query({
query: () => ({
url: api.FB_GET_PAGE_PHOTOS_URL,
method: 'GET'
}),
})
})
})
export const {
useGetPagePhotosQuery
} = facebookSlice
serviceSlice.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "../../config/constants";
export const serviceSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: api.API_BASE_URL,
}),
endpoints: (builder) => ({
getServices: builder.query({
query: () => ({
url: '/',
method: 'GET'
}),
})
})
})
export const {
useGetServicesQuery
} = serviceSlice
bookingSlice.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { api } from "../../config/constants";
export const bookingSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: api.API_BASE_URL,
}),
endpoints: (builder) => ({
getBookings: builder.query({
query: () => ({
url: '/bookings',
method: 'GET'
}),
}),
createBooking: builder.mutation({
query: (booking) => ({
url: '/bookings/create',
method: 'POST',
headers:{},
body: booking
}),
})
})
})
export const {
useGetBookingsQuery,
useCreateBookingMutation
} = bookingSlice
store.js
import { configureStore } from '@reduxjs/toolkit';
import { facebookSlice } from './features/api/facebookSlice';
import { bookingSlice } from './features/api/bookingSlice';
import { serviceSlice } from './features/api/serviceSlice';
const store = configureStore({
reducer: {
[facebookSlice.reducerPath]: facebookSlice.reducer,
[bookingSlice.reducerPath]: bookingSlice.reducer,
[serviceSlice.reducerPath]: serviceSlice.reducer
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat([bookingSlice.middleware, serviceSlice.middleware])
});
export default store;
index.js
import React, { Children } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import 'semantic-ui-css/semantic.min.css'
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import Layout from './layout';
import Home from './components/home/home'
import Booking from './components/booking/booking'
import { ApiProvider } from '@reduxjs/toolkit/dist/query/react';
import { serviceSlice } from './features/api/serviceSlice';
import { Hallway } from './components/hallway/hallway';
import { Provider } from 'react-redux';
import store from './store';
const router = createBrowserRouter([
{
path: '/',
element: <Layout />,
children: [
{
path: "",
element: <Home />
},
{
path: "booking",
element: <Booking />
},
{
path: "hallway",
element: <Hallway />
}
]
}
])
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<RouterProvider router={router} />
</Provider>
</React.StrictMode>
);
reportWebVitals();
You have multiple API slices all using the default reducerPath
value, e.g. "api"
and this creates a conflict.
See reducerPath
.
The
reducerPath
is a unique key that your service will be mounted to in your store. If you callcreateApi
more than once in your application, you will need to provide a unique value each time. Defaults to'api'
.
You are passing an array to the getDefaultMiddleware
function instead of just passing the middlewares directly.
const store = configureStore({
reducer: {
[facebookSlice.reducerPath]: facebookSlice.reducer, // api: facebookSlice.reducer
[bookingSlice.reducerPath]: bookingSlice.reducer, // api: bookingSlice.reducer
[serviceSlice.reducerPath]: serviceSlice.reducer // api: serviceSlice.reducer
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat([ // <-- passing array, not middleware
bookingSlice.middleware,
serviceSlice.middleware
])
});
Give each API slice a unique reducer path value.
export const facebookSlice = createApi({
reducerPath: 'facebookApi', // <-- unique among API slices
baseQuery: fetchBaseQuery({
baseUrl: api.FACEBOOK_GRAPH_URL,
}),
endpoints: (builder) => ({
getPagePhotos: builder.query({
query: () => ({
url: api.FB_GET_PAGE_PHOTOS_URL,
method: 'GET'
}),
})
})
});
export const serviceSlice = createApi({
reducerPath: 'serviceApi', // <-- unique among API slices
baseQuery: fetchBaseQuery({
baseUrl: api.API_BASE_URL,
}),
endpoints: (builder) => ({
getServices: builder.query({
query: () => ({
url: '/',
method: 'GET'
}),
})
})
});
export const bookingSlice = createApi({
reducerPath: 'bookingApi', // <-- unique among API slices
baseQuery: fetchBaseQuery({
baseUrl: api.API_BASE_URL,
}),
endpoints: (builder) => ({
getBookings: builder.query({
query: () => ({
url: '/bookings',
method: 'GET'
}),
}),
createBooking: builder.mutation({
query: (booking) => ({
url: '/bookings/create',
method: 'POST',
headers: {},
body: booking
}),
})
})
});
Pass the middlewares directly, .concat
handles "merging" them.
const store = configureStore({
reducer: {
[facebookSlice.reducerPath]: facebookSlice.reducer,
[bookingSlice.reducerPath]: bookingSlice.reducer,
[serviceSlice.reducerPath]: serviceSlice.reducer
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware()
.concat(
facebookSlice.middleware,
bookingSlice.middleware,
serviceSlice.middleware
)
});