77

I have one piece of middleware already plugged in, redux-thunk, and I'd like to add another, redux-logger.

How do I configure it so my app uses both pieces of middleware? I tried passing in an array of [ReduxThunk, logger] but that didn't work.

Code:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import logger from 'redux-logger';

import App from './components/app';
import reducers from './reducers';
require('./style.scss');

const createStoreWithMiddleware = applyMiddleware(ReduxThunk)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>,
  document.querySelector('#app')
);
norbitrial
  • 14,716
  • 7
  • 32
  • 59
doctopus
  • 5,349
  • 8
  • 53
  • 105

7 Answers7

124

applyMiddleware takes each piece of middleware as a new argument (not an array). So just pass in each piece of middleware you'd like.

const createStoreWithMiddleware = applyMiddleware(ReduxThunk, logger)(createStore);
Andy Noelker
  • 10,949
  • 6
  • 35
  • 47
31

answer of andy's is good, but, consider your middlewares growing, below codes will be better:

const middlewares = [ReduxThunk, logger]
applyMiddleware(...middlewares)
chen Jacky
  • 507
  • 4
  • 8
  • 2
    Thank you, but i add redux-thunk `const store = createStore(reducer, composeWithDevTools(applyMiddleware(thunk, ...middleware)));` – Sergey Sep 28 '18 at 10:32
  • Initial post stated that array was not working with redux_thunk...same issue for me – james murphy Apr 24 '22 at 02:30
12

applyMiddleware should pass into createStore as the second parameter. applyMiddleware can have multiple middlewares as arguments.

const store = createStore(reducers, applyMiddleware(ReduxThunk, logger));

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#app')
);
Tharaka Wijebandara
  • 7,955
  • 1
  • 28
  • 49
  • 1
    If I do this I get "createStore is not a function". Any idea where this error could be coming from? I'm trying to use redux-saga and remote-redux-devtools – Daniel Reina Sep 09 '17 at 19:06
  • Probably you are not importing `createStore` correctly or using an old version of redux. – Tharaka Wijebandara Sep 09 '17 at 19:14
  • 3
    the problem was that one of the middleware didn't need `applyMiddleware`, so I had to use `compose(applyMiddleware(saga), devtools())`. Thanks! – Daniel Reina Sep 09 '17 at 19:24
2

This is how to apply one or many middlewares :

import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import {rootReducer} from "../reducers"; // Import your combined reducers ;)

const middleWares = [thunk, logger]; // Put the list of third part plugins in an array 

// Create the store with the applied middleWares and export it
export const store = createStore(rootReducer, applyMiddleware(...middleWares));

Now import the store exported recently in your index.js and pass it to the Provider component. Your index.js file should looks like :

... ...

import {Provider} from 'react-redux';
import {store} from './store';

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, 
document.getElementById('root'));

That's all !

Mustapha GHLISSI
  • 1,485
  • 1
  • 15
  • 16
1

it may be a bit late of an answer but my problem was adding the devtools with the middlewares, hope this helps somebody

 // imports.. 
 import { composeWithDevTools } from "redux-devtools-extension";

  const store = createStore(
     Reducer,
     persistedState,
    composeWithDevTools(applyMiddleware(ReduxThunk, promiseMiddleware))
 );
Harvester Haidar
  • 531
  • 7
  • 16
1

You can simply pass the middlewares in the comma separated manner like the following code:

const store = createStore(reducer, applyMiddleware(thunk, logger));

Note: Please import the applyMiddlware, thunk, and logger at the top.

0
export default configureStore({
  reducer: {
    products: productReducer,
    cart: cartReducer,
    [productsApi.reducerPath]: productsApi.reducer,
    userAuth: authSlice,
  },

  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false
    }).concat(productsApi.middleware),

});