如果您只有一个减速器,则不需要combineReducers(). 直接使用就可以了:
const initialState = {
sources: [],
left: {},
right: {}
}
function app(state = initialState, action) {
switch (action.type) {
case 'ADD_SOURCE':
return Object.assign({}, state, {
sources: [...state.sources, action.newSource]
})
case 'ADD_SOURCE_TO_LEFT':
return Object.assign({}, state, {
left: Object.assign({}, state.left, {
[action.sourceId]: true
})
})
case 'ADD_SOURCE_TO_RIGHT':
return Object.assign({}, state, {
right: Object.assign({}, state.right, {
[action.sourceId]: true
})
})
default:
return state
}
}
现在您可以使用该减速器创建一个商店:
import { createStore } from 'redux'
const store = createStore(app)
并将一个组件连接到它:
const mapStateToProps = (state) => ({
sources: state.sources
})
然而,你的减速器很难阅读,因为它一次更新了许多不同的东西。现在,这是您想要将其拆分为几个独立的减速器的时刻:
function sources(state = [], action) {
switch (action.type) {
case 'ADD_SOURCE':
return [...state.sources, action.newSource]
default:
return state
}
}
function left(state = {}, action) {
switch (action.type) {
case 'ADD_SOURCE_TO_LEFT':
return Object.assign({}, state, {
[action.sourceId]: true
})
default:
return state
}
}
function right(state = {}, action) {
switch (action.type) {
case 'ADD_SOURCE_TO_RIGHT':
return Object.assign({}, state, {
[action.sourceId]: true
})
default:
return state
}
}
function app(state = {}, action) {
return {
sources: sources(state.sources, action),
left: left(state.left, action),
right: right(state.right, action),
}
}
这更容易维护和理解,也更容易独立更改和测试 reducer。
最后,作为最后一步,我们可以使用combineReducers()生成 root appreducer 而不是手工编写:
// function app(state = {}, action) {
// return {
// sources: sources(state.sources, action),
// left: left(state.left, action),
// right: right(state.right, action),
// }
// }
import { combineReducers } from 'redux'
const app = combineReducers({
sources,
left,
right
})
使用combineReducers()而不是手动编写 root reducer没有什么大的好处,只是它的效率稍微高一些,并且可能会为您节省一些拼写错误。此外,您可以在您的应用程序中多次应用此模式:以嵌套方式将不相关的减速器多次组合到单个减速器中是可以的。
所有这些重构都不会对组件产生影响。
我建议您观看我关于 Redux 的免费 Egghead 课程,该课程涵盖了这种reducer 组合模式并展示了如何combineReducers()实现。