javascriptreduximmutable.jsredux-immutable

Using Redux.createStore with Immutable throws "reducer is not a function (How to use Redux with Immutable.js ans composeEnhancers)


I wrote this code to create Redux store:

import {combineReducers} from 'redux-immutable'

const MyAppReducers = combineReducers({
    Node1: Node1Reducer,
    Node2: Node2Reducer,
    Node3: Node3Reducer,
    Node4: Node4Reducer
})

let store = createStore(
    MyAppReducers,
    composeEnhancers(
        applyMiddleware(
            thunkMiddleware,
            ApiMiddleware,
            loggerMiddleware
        )
    )
)

The result of this configuration is a plain object with inside the Immutable.Map()s:

{
    Node1: Immutable.Map(),
    Node2: Immutable.Map(),
    Node3: Immutable.Map(),
    Node4: Immutable.Map()
}

I want, instead, that all the state tree is an Immutable.Map().

So I tried to pass to combineReducers() directly an Immutable.Map() object:

const MyAppReducers = combineReducers(Immutable.Map({
    Node1: Node1Reducer,
    Node2: Node2Reducer,
    Node3: Node3Reducer,
    Node4: Node4Reducer
}))

But this throws an error in the console:

Uncaught TypeError: reducer is not a function

at combineReducers.js:39

at Array.forEach ()

at combineReducers.js:36

at Map.withMutations (immutable.js:1353)

at combineReducers.js:35

at computeNextEntry (:2:27469)

at recomputeStates (:2:27769)

at :2:31382

at dispatch (createStore.js:165)

at createStore (createStore.js:240)

The documentation of redux-immutable states that I should pass the initialState as a second argument of the createStore function, but my second argument is currently the composeEnhancers function that I need to configure middlewares and other things.

How can I make the entire state tree be an Immutable.Map() object?


Solution

  • The built-in combineReducers function expects that the state it sees is a plain Javascript object.

    If you want the state tree to be an Immutable.js Map instead, you need to use a different function, like the one provided by redux-immutable or other Redux/immutable interop libs.

    Note that the Redux createStore function can either be called as:

    createStore(rootReducer, initialState, composedEnhancers);
    createStore(rootReducer, composedEnhancers);
    

    So, pass your initial Immutable.js Map as the second argument.