使用Redux.createStore和Immutable throws“reducer不是一个函数(如何使用Redux与Immutable.js和composeEnhancers)

时间:2018-01-03 19:08:03

标签: javascript redux immutable.js redux-immutable

我编写此代码来创建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() s内的普通对象:

{
    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
}))

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

  

未捕获的TypeError:reducer不是函数

     

在combineReducers.js:39

     

在Array.forEach()

     

在combineReducers.js:36

     

在Map.withMutations(immutable.js:1353)

     

在combineReducers.js:35

     

at computeNextEntry(:2:27469)

     

at recomputeStates(:2:27769)

     

at:2:31382

     发送时的

(createStore.js:165)

     

在createStore(createStore.js:240)

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

如何将整个州树变成Immutable.Map()个对象?

2 个答案:

答案 0 :(得分:0)

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

如果您希望状态树为Immutable.js Map,则需要使用其他功能,例如redux-immutableother Redux/immutable interop libs提供的功能。 / p>

请注意,Redux createStore函数可以被称为:

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

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

答案 1 :(得分:0)

对于可能遇到同样问题的人来说,完整的解决方案就是:

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树。{/ p>