Redux源码解析之combineReducers

629 阅读1分钟

1.概述

Redux在createStore的时候,只接受一个reducer作为参数。所以我们要把所有小的reducers合并成一个大的reducer,这时就要用到一个叫combineReducers({})的方法。

2.代码实现

把多个reducer合并成一个reducer,即,在一个函数里把reducers循环执行一遍,并且这个函数要遵循(previousState, action) => newState格式。

注意:还需要把每个reducer的initState合并成一个rootState

为了便于理解,简易版的实现代码如下:

function combineReducers(reducers) {
    return (state={}, action) => {
        let obj={}; // 每次都返回一个新的rootstate
        for(let key in reducers){
            // 把每个子reducer的state 赋值给rootState相应的属性上
            obj[key]= reducers[key](state[key], action);
        }
        return obj;
    }
}
/**
* 当然combineReducers的源码共181行,其中包含很多逻辑判断,类型校验等的处理,
* 但是主要的逻辑就是这些,这几行代码已经可以清楚的描述出comnbineReducers在
* 整个redux的流程中的作用
*/

3.栗子分析

例如要把两个小的CounterReducer和TodoReducer合并成一个大的reducer:

let initSCountState = { num: 9 };
function CounterReducer(state = initState, action) {
    switch (action.type) {
        case 'add': return { ...state, num: state.num + 1 };
        case 'minus': return { ...state, num: state.num - 1 };
        default: break;
    }
    return state;
}

let initTodoItems = [];
function TodoReducer(state = initTodoItems, action) {
    switch (action.type) {
        case 'addItem': return state.slice().concat(action.item);
        case 'removeAll': return [];
        default: break;
    }
    return state;
}

let reducers = {
    CounterReducer: CounterReducer,
    TodoReducer: TodoReducer,
};

let rootReducer = combineReducers(reducers);