reactjsreduxreact-reduxredux-toolkitredux-thunk

redux tookit when using a middleware builder function, an array of middleware must be returned


So I'm getting Uncaught Error: when using a middleware builder function, an array of middleware must be returned

This is my code

import {
  configureStore,
  compose,
  combineReducers,
  applyMiddleware
} from "@reduxjs/toolkit";
import thunk from "redux-thunk";

const rootReducer = combineReducers({});

const middleware = applyMiddleware(thunk);
const composeWithDevTools = 
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const composedMiddleWare = composeWithDevTools(middleware)

const store = configureStore({
  reducer: rootReducer,
  middleware: composedMiddleWare,
  devTools: 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
})

export default store;

I have no idea what's wrong and searching doesn't seem to be returning any useful result.


Solution

  • configureStore from redux-toolkit (RTK) works differently from the redux createStore function. The middleware property accepts an array of middleware to install and RTK handles applying them.

    See configureStore

    /**
     * An array of Redux middleware to install. If not supplied, defaults to
     * the set of middleware returned by `getDefaultMiddleware()`.
     */
    middleware?: ((getDefaultMiddleware: CurriedGetDefaultMiddleware<S>) => M) | M
    

    Note that while applyMiddleware is re-exported from redux that

    You should not need to use this directly.

    The following would be the code you'd use:

    import { configureStore, combineReducers } from "@reduxjs/toolkit";
    import thunk from "redux-thunk";
    
    const rootReducer = combineReducers({});
    
    const store = configureStore({
      reducer: rootReducer,
      middleware: [thunk], // <-- array of middlewares to install/apply
      devTools: window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    });
    
    export default store;
    

    RTK also ships with opinionated optimizations:

    1. The devTools are enabled by default, you'll only use this if you have custom needs.

    2. Thunk middleware is also already included with the default middleware, e.g. if no middleware property is provided, then getDefaultMiddleware is provided and returns the following middleware value, which includes the thunk middleware:

      const middleware = [
        actionCreatorInvariant,
        immutableStateInvariant,
        thunk, // <-- included thunk middleware!
        serializableStateInvariant,
      ]
      

      Again, you'll really only need to specify the middleware property if you need to customize the immutability or serialization middlewares.

    Your store configuration can be reduced to the following:

    import { configureStore, combineReducers } from "@reduxjs/toolkit";
    
    const rootReducer = combineReducers({});
    
    const store = configureStore({
      reducer: rootReducer,
    });
    
    export default store;
    

    Both the thunk middleware and dev tools will be active and working.