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

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

我写了这段代码来创建 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
        )
    )
)

此配置的结果是 Immutable.Map() 内的普通对象:

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

相反,我希望所有状态树都是 Immutable.Map()

所以我试图直接传递给 combineReducers() 一个 Immutable.Map() 对象:

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

但这会在控制台中引发错误:

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)

redux-immutable 的文档指出我应该将 initialState 作为 createStore 函数的第二个参数传递,但我的第二个参数目前是 composeEnhancers 函数我需要配置中间件和其他东西。

如何让整个状态树成为一个 Immutable.Map() 对象?

内置 combineReducers 函数期望它看到的状态是一个普通的 Javascript 对象。

如果您希望状态树成为 Immutable.js Map,则需要使用不同的函数,例如 redux-immutable or other Redux/immutable interop libs.

提供的函数

请注意,Redux createStore 函数可以调用为:

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

因此,将您的初始 Immutable.js Map 作为第二个参数传递。

仅供可能遇到相同问题的人使用,完整的解决方案是:

import {combineReducers} from 'redux-immutable'
import {fromJS} from 'immutable'
import { createStore, applyMiddleware } from 'redux';
import ThunkMiddleware from 'redux-thunk'
import {createLogger} from 'redux-logger'

const MyAppInitialState = fromJS({
    Node1: {
        entities: {},
        ui: {}
    },
    Node2: {
        entities: {},
        ui: {}
    },
    Node3: {
        entities: {},
        ui: {}
    },
    Node4: {
        entities: {},
        ui: {}
    }
})

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

const LoggerMiddleware = createLogger()

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

// Example of a reducer (just for completeness)
const Node1Reducer = (state = fromJS({entities: {}, ui: {}}), action) => {
    switch (action.type) {
        ...
        default:
            return state
    }
}

通过此配置,我现在可以将 Immutable.jsRedux 一起使用,将整个 state 作为一棵 Immutable 树。