7-多个Reducers的使用(combineReducers))

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.

你可能感兴趣的:(7-多个Reducers的使用(combineReducers)))