Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux: the previous state received by the reducer has unexpected type of "Function"

When I add middleware for chrome extension, reducers stop working properly on site (but chrome/redux debug tool works) + I get following error in console:

The previous state received by the reducer has unexpected type of "Function". Expected argument to be an object with the following keys: "auth", "common", "home"

Here is code:

import { applyMiddleware, createStore } from 'redux';
import { promiseMiddleware, localStorageMiddleware } from './middleware';
import reducer from './reducer';

const middleware = applyMiddleware(promiseMiddleware, localStorageMiddleware);

const store = createStore(reducer, middleware,
      window.devToolsExtension ? window.devToolsExtension() : f => f);

export default store;

If I remove chrome part:

,window.devToolsExtension ? window.devToolsExtension() : f => f

If works normal again.

like image 302
Nema Ga Avatar asked Jun 28 '16 10:06

Nema Ga


People also ask

Are the pure functions which takes the previous state and an action and return the next state?

Reducers are just pure functions that take the previous state and an action, and return the next state. Remember to return new state objects, instead of mutating the previous state.

Which of the things should not be done inside a reducer function in Redux?

Following are the things you should never do inside a reducer: Mutate reducer's arguments; Perform side effects like database calls, API calls, and routing transitions; Call non-pure functions, e.g., Date.

How do we return a new state in reducers of Redux?

If the state of the object changes, the component has to re-render. In redux, Updation of state happens in the reducer function. Basically reducer function returns a new state by performing an action on the initial state. Below, is an example of how we can declare the initial state of an application.

Which method helps you retrieve the current state of your Redux store?

getState. It helps you retrieve the current state of your Redux store.


Video Answer


2 Answers

createStore takes up to 3 arguments. If the second argument is a function it assumes that your second argument is the store enhancer. If it is an object or there are 3 arguments present it assumes that the argument is your initial state. See here.

Your middleware variable is a store enhancer and the chrome extension is also an enhancer:

window.devToolsExtension ? window.devToolsExtension() : f => f

You have to compose both in a single function:

import { applyMiddleware, createStore, compose } from 'redux';
import { promiseMiddleware, localStorageMiddleware } from './middleware';
import reducer from './reducer';

const middleware = applyMiddleware(promiseMiddleware, localStorageMiddleware);

const store = createStore(
  reducer,
  compose(middleware, window.devToolsExtension ? window.devToolsExtension() : f => f)
);

export default store;

Documentation for this can be found here.

like image 99
Herku Avatar answered Oct 04 '22 07:10

Herku


createStore accepts the following arguments:

  • reducer
  • preloaded state
  • enhancer

If only two arguments supplied and the second argument is a function, then it's considered to be an enhancer. See more in the source code.

If you want to use Redux devtools, then you should compose it as an additional enhancer.

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

    const store = createStore(
      reducer,
      compose(
        middleware,
        window.devToolsExtension ? window.devToolsExtension() : f => f
      )
    )

Hope that helps. Pozdrav 😉

like image 39
Grgur Avatar answered Oct 04 '22 07:10

Grgur