redux-devtools-extension: Actions must be plain objects. Use custom middleware for async actions. :(

Hi!

Your chrome extension is producing the following error with my application:

Actions must be plain objects. Use custom middleware for async actions.

We use redux with the thunk middleware (and extra argument) + react-router-redux middleware (looks like this):

  const router = routerMiddleware(browserHistory)
  const store = create(
    rootReducer,
    getInitialState(),
    applyMiddleware(thunk.withExtraArgument(api), router)
  )

And a sample of how our actions are defined (which are cuasing teh problems) look like this:

export const authenticate = (code) => {
  return (dispatch, getState, api) => {
    return null
  }
}

Am I doing something wrong? Without your extension, the app compiles and runs fine. Any guidance would be super appreciated, thanks!

If you need more info, let me know!! ❤️

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 21 (7 by maintainers)

Commits related to this issue

Most upvoted comments

Yep, deployed and fixed it.

I was doing this before:

const create = window.devToolsExtension
  ? window.devToolsExtension()(createStore)
  : createStore

const router = routerMiddleware(browserHistory)
const store = create(
  rootReducer,
  getInitialState(),
  applyMiddleware(thunk.withExtraArgument(api), router)
)

But switching it to this fixed the error:

  const router = routerMiddleware(browserHistory)
  const store = createStore(
    rootReducer,
    getInitialState(),
    compose(
      applyMiddleware(thunk.withExtraArgument(api), router),
      window.devToolsExtension ? window.devToolsExtension() : f => f
    )
  )

thanks for the help!

I don’t see the extension’s enhancer in the provided snippet. Should be:

  const router = routerMiddleware(browserHistory)
  const store = create(
    rootReducer,
    getInitialState(),
    compose(
      applyMiddleware(thunk.withExtraArgument(api), router),
      window.devToolsExtension ? window.devToolsExtension() : f => f
    )
  )

Note that the extension’s enhancer should be always last in the compose. Just in case, compose is imported from Redux.

Also, if you want to dispatch actions remotely, after that code you also have to add

if (window.devToolsExtension) window.devToolsExtension.updateStore(store)

So, the extension would know about the middlewares.

Please let me know what exactly was the problem.

@swp44744, you’re mixing the old Redux API with the new one. Also the extension should be applied as store enhancer not as a middleware.

Here’s how it should be:

- import { createStore, applyMiddleware } from 'redux';
+ import { createStore, applyMiddleware, compose } from 'redux';

- const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
+ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+ const store = createStore(reducer, composeEnhancers(applyMiddleware(ReduxPromise)));

- <Provider store={createStoreWithMiddleware(reducers,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())}> <Router history = {browserHistory} routes={routes}/> </Provider>
+ <Provider store={store}> <Router history = {browserHistory} routes={routes}/> </Provider>

For me, this error came because of a typo. I forgot to return the inner function.

I wrote this:

export const fetchStuff = someParameter => {
  dispatch => {
    // Do your thing...
  }
}

The correct way is this:

export const fetchStuff = someParameter => dispatch => {
  // Do your thing...
}

Thanks Buddy this approach worked, I also realized that I was getting that error only when I am doing API call in my action through axios and returning response to reducer through “.then” like below:

const response = axios.get(url, { params: { query: inputData, maxResults: ‘10’ } }) .then(function (response) { return{ type: ACTION_TYPE, payload: response }; }) .catch(function (error) { console.log(error); });

Redux version is 3.6.0.

Actually, investigating your second question lead me to realize I was importing actions improperly, meaning they didn’t get passed to dispatch correctly, which caused the error. It was getting passed as ‘undefined’, which redux-thunk isn’t designed to handle! So, in short, I’m an idiot! But, at least I am an idiot with a solved problem now!

Thanks @zalmoxisus for the help!

@lakshya-8

try something like this

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducers,
  undefined,
  composeEnhancers(
    applyMiddleware(...middlewares)
  )
)