代码之家  ›  专栏  ›  技术社区  ›  Aerendir

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

  •  1
  • Aerendir  · 技术社区  · 7 年前

    我写这段代码是为了创建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()
    }
    

    相反,我希望所有的状态树都是 不变的地图() .

    所以我试着传给 combineReducers() 直接an 不变的地图() 对象:

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

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

    未捕获类型错误:减速机不是函数

    在联合传感器。js:39

    at阵列。forEach()

    在联合传感器。js:36

    在地图上。With突变(immutable.js:1353)

    在联合传感器。js:35

    在ComputeExtentry(:2:27469)

    在重新计算时(:2:27769)

    电话:2:31382

    发送时(createStore.js:165)

    在createStore(createStore.js:240)

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

    如何使整个状态树成为 不变的地图() 对象

    2 回复  |  直到 7 年前
        1
  •  2
  •   Aerendir    7 年前

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

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

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

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

    所以,通过你的首字母 不变的js公司 地图 作为第二个参数。

        2
  •  0
  •   Aerendir    7 年前

    对于可能有相同问题的人,完整的解决方案是:

    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.js 具有 Redux 拥有整个 state 作为 Immutable