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.js
与 Redux
一起使用,将整个 state
作为一棵 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()
内的普通对象:
{
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.js
与 Redux
一起使用,将整个 state
作为一棵 Immutable
树。