美文网首页深入浅出Redux系列
7-多个Reducers的使用(combineReducers)

7-多个Reducers的使用(combineReducers)

作者: 钢笔先生 | 来源:发表于2020-01-29 15:50 被阅读0次

    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)

        本文链接:https://www.haomeiwen.com/subject/ofavthtx.html