React RTK报错排查及多Slice的Store配置优化咨询
问题解决与优化方案
1. 解决「Cannot read properties of undefined (reading 'merge')」错误
所有RTK Query的API切片必须使用唯一的reducerPath,否则会导致状态合并冲突。修改每个切片的reducerPath为专属名称:
FacebookSlice 修改后
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { api } from "../../config/constants"; export const facebookSlice = createApi({ reducerPath: 'facebookApi', // 唯一标识 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: 'serviceApi', // 唯一标识 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: 'bookingApi', // 唯一标识 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
2. 解决「Middleware for RTK-Query API at reducerPath 'apifb' has not been added to the store」警告
警告原因是facebookSlice的中间件未添加到store中,同时优化多切片场景下的中间件合并逻辑:
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'; // 统一收集所有RTK Query中间件 const apiMiddlewares = [ facebookSlice.middleware, bookingSlice.middleware, serviceSlice.middleware ]; const store = configureStore({ reducer: { [facebookSlice.reducerPath]: facebookSlice.reducer, [bookingSlice.reducerPath]: bookingSlice.reducer, [serviceSlice.reducerPath]: serviceSlice.reducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(...apiMiddlewares) // 展开数组批量合并 }); export default store;
后续新增API切片时,只需将新切片的middleware加入apiMiddlewares数组即可,无需修改合并逻辑。
3. 移除冗余代码
你的index.js中引入了ApiProvider但未实际使用,由于所有API切片已接入Redux store,无需单独使用ApiProvider,直接保留Redux的Provider即可:
index.js 修改后
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import 'semantic-ui-css/semantic.min.css' 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 { Hallway } from './components/hallway/hallway'; import { Provider } from 'react-redux'; import store from './store'; import reportWebVitals from './reportWebVitals'; 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();
内容的提问来源于stack exchange,提问作者Abhra Sarkar
相关产品推荐
相关产品推荐

