Time: 20200129
在前文我们知道,要新增一个买卖品类:冰激凌。
即增加一个reducer
。
但用一个reducer
也能解决问题。我们先看这种方法是如何实现的。
代码如下:
// index.js
// import redux from 'redux'
const redux = require('redux') // nodejs version import
// this is a function
const createStore = redux.createStore // not redux.createStore()
// console.log("From index.js")
const BUY_CAKE = 'BUY_CAKE'
const BUY_ICECREAME = 'BUY_ICECREAM'
// action creator
function buyCake(params) {
action = {
type: BUY_CAKE,
info: 'first redux action',
}
return action
}
function buyIceCream() {
action = {
type: BUY_ICECREAME,
info: 'second redux action'
}
return action
}
// (previousState, action) => newState
const initialState = {
numOfCakes: 10,
numOfIceCreams: 20,
}
// 定义一个reducer,这里已经把初始状态放到reducer中了
const reducer = (state=initialState, action) => {
switch (action.type) {
case BUY_CAKE:
return {
...state,
numOfCakes: state.numOfCakes - 1
}
case BUY_ICECREAME:
return {
...state,
numOfIceCreams: state.numOfIceCreams - 1
}
default:
return state
}
}
// create a store
const store = createStore(reducer)
console.log('initial state: ', store.getState())
const unsubscribe = store.subscribe(() => console.log('Updated state', store.getState()))
store.dispatch(buyCake())
store.dispatch(buyCake())
store.dispatch(buyCake())
store.dispatch(buyIceCream())
store.dispatch(buyIceCream())
// 注销监听事件
unsubscribe()
执行,node index.js
,结果如下:
initial state: { numOfCakes: 10, numOfIceCreams: 20 }
Updated state { numOfCakes: 9, numOfIceCreams: 20 }
Updated state { numOfCakes: 8, numOfIceCreams: 20 }
Updated state { numOfCakes: 7, numOfIceCreams: 20 }
Updated state { numOfCakes: 7, numOfIceCreams: 19 }
Updated state { numOfCakes: 7, numOfIceCreams: 18 }
多个reducers
为什么要拆分为多个reducers呢?
随着要卖的产品的增多,相应的处理函数也越来越多,这样的话,一个reducer
会越来越臃肿。
因此,适当拆分,代码更易维护,且逻辑更加清晰。
其实拆分reducers
和相应的初始态并不难,需要思考的点在于,如何初始化一个store
。
这就涉及到,combineReducers
的使用了。
代码总体如下:
// import redux from 'redux'
const redux = require('redux') // nodejs version import
// this is a function
const createStore = redux.createStore // not redux.createStore()
const combineReducers = redux.combineReducers
// console.log("From index.js")
const BUY_CAKE = 'BUY_CAKE'
const BUY_ICECREAME = 'BUY_ICECREAM'
// action creator
function buyCake(params) {
action = {
type: BUY_CAKE,
info: 'first redux action',
}
return action
}
function buyIceCream() {
action = {
type: BUY_ICECREAME,
info: 'second redux action'
}
return action
}
// (previousState, action) => newState
// const initialState = {
// numOfCakes: 10,
// numOfIceCreams: 20,
// }
// 拆分为多个初始状态
const initialCakeState = {
numOfCakes: 10,
}
const initialIceCreamState = {
numOfIceCreams: 20,
}
// 定义一个reducer,这里已经把初始状态放到reducer中了
// const reducer = (state=initialState, action) => {
// switch (action.type) {
// case BUY_CAKE:
// return {
// ...state,
// numOfCakes: state.numOfCakes - 1
// }
// case BUY_ICECREAME:
// return {
// ...state,
// numOfIceCreams: state.numOfIceCreams - 1
// }
// default:
// return state
// }
// }
// 拆分reducers
const cakeReducer = (state=initialCakeState, action) => {
switch (action.type) {
case BUY_CAKE:
return {
...state,
numOfCakes: state.numOfCakes - 1
}
default:
return state
}
}
const iceCreamReducer = (state=initialIceCreamState, action) => {
switch (action.type) {
case BUY_ICECREAME:
return {
...state,
numOfIceCreams: state.numOfIceCreams - 1
}
default:
return state
}
}
const rootReducer = combineReducers({
cake: cakeReducer,
iceCream: iceCreamReducer
})
// create a store
// const store = createStore(reducer)
const store = createStore(rootReducer)
console.log('initial state: ', store.getState())
const unsubscribe = store.subscribe(() => console.log('Updated state', store.getState()))
store.dispatch(buyCake())
store.dispatch(buyCake())
store.dispatch(buyCake())
store.dispatch(buyIceCream())
store.dispatch(buyIceCream())
// 注销监听事件
unsubscribe()
执行结果会略有不同:
initial state: { cake: { numOfCakes: 10 }, iceCream: { numOfIceCreams: 20 } }
Updated state { cake: { numOfCakes: 9 }, iceCream: { numOfIceCreams: 20 } }
Updated state { cake: { numOfCakes: 8 }, iceCream: { numOfIceCreams: 20 } }
Updated state { cake: { numOfCakes: 7 }, iceCream: { numOfIceCreams: 20 } }
Updated state { cake: { numOfCakes: 7 }, iceCream: { numOfIceCreams: 19 } }
Updated state { cake: { numOfCakes: 7 }, iceCream: { numOfIceCreams: 18 } }
抽出来看就是,这个状态树不再是扁平的,而是按照combineReducers
时指定的键名来划分小区间了。
{
cake: { numOfCakes: 7 },
iceCream: { numOfIceCreams: 18 }
}
这个特性曾经在我写项目的时候,困扰了我一段时间,最后知道了这个特性才弄懂状态树的使用方式。
combineReducers
const combineReducers = redux.combineReducers
const rootReducer = combineReducers({
cake: cakeReducer,
iceCream: iceCreamReducer
})
const store = createStore(rootReducer)
END.