【问题标题】:Using Redux.createStore with Immutable throws "reducer is not a function (How to use Redux with Immutable.js ans composeEnhancers)将 Redux.createStore 与 Immutable 一起使用会抛出“reducer 不是函数(如何将 Redux 与 Immutable.js 和 composeEnhancers 一起使用)
【发布时间】:2018-01-03 19:08:03
【问题描述】:

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

所以我尝试直接将Immutable.Map() 对象传递给combineReducers()

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

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

未捕获的类型错误:reducer 不是函数

在 combineReducers.js:39

在 Array.forEach ()

在 combineReducers.js:36

在 Map.withMutations (immutable.js:1353)

在 combineReducers.js:35

在 computeNextEntry (:2:27469)

在重新计算状态 (:2:27769)

在:2:31382

分派时 (createStore.js:165)

在 createStore (createStore.js:240)

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

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

【问题讨论】:

    标签: javascript redux immutable.js redux-immutable


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 抱歉,错过了。更新了我的答案。
    • 我尝试将初始状态传递给createStore,但无论如何它都会导致关于未知属性的错误:在reducer 接收的先前状态中发现意外属性“StateRoot”。预计会找到已知的 reducer 属性名称之一:“size”、“_root”、“__ownerID”、“__hash”、“__altered”。意外的属性将被忽略。无论如何都会出现错误“Uncaught TypeError:reducer is not a function”。拜托,您能否扩展您的答案,为我提供更多代码,因为我无法解决当前的建议?
    【解决方案2】:

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

    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 树。

    【讨论】:

      猜你喜欢
      • 2018-10-07
      • 2015-03-08
      • 1970-01-01
      • 2021-08-14
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-01-24
      • 2020-11-28
      相关资源
      最近更新 更多