redux v3.7.2源码解读与学习之 combineReducers

redux是什么、有什么作用,解决什么问题,如果你还不知道,请先去这里: redux中文文档

下面的文章适合对redux有一定理解和使用经验的人

项目github地址:github.com/wangweiange…

如果你觉得对你有帮助的话记得给我一个star 呢


combineReducers是redux的一个核心辅助函数,把多个reducer 合并成一个reducer集合,按key值来区分各个reducer,最终大致数据结构如下:

{
  reducer1: ...
  reducer2: ...
}复制代码



最直白的注解,就是干了下面这个事情返回了combination函数。

//有三个函数
let initstate={number:1}
function a(state=initstate,action){
    ...
}
function b(state=initstate,action){
    ...
}
function c(state=initstate,action){
    ...
}

//调用combineReducers方法
const reducers = combineReducers({
    a,
    b,
    c
})

//得到combination这个function  
function combination(state = {}, action){
    const nextState = {
        a:{number:1},
        b:{number:1},
        c:{number:1}
    }

    return nextState
}

//调用的得到 nextState 最终赋值给 createStore方法里面的currentState变量
currentState = combination(currentState,action)复制代码



下面让我们来看看源码,我对源码进行了很大的精简,代码如下:

export default function combineReducers(reducers) {
    const finalReducers = reducers
    const finalReducerKeys = Object.keys(finalReducers)

    return function combination(state = {}, action) {
        let hasChanged = false
        const nextState = {}
        for (let i = 0; i < finalReducerKeys.length; i++) {
            const key = finalReducerKeys[i]
            const reducer = finalReducers[key]
            const previousStateForKey = state[key]
            const nextStateForKey = reducer(previousStateForKey, action)
            nextState[key] = nextStateForKey
            hasChanged = hasChanged || nextStateForKey !== previousStateForKey
        }
        return hasChanged ? nextState : state
    }
}复制代码


真正的核心代码就这么多,完全可以自己写一个。

给一段测试代码,根据这段代码去理解上面的combineReducers函数

const initialStateHome = {
    home:10,
    cart:20
}

function home (state = initialStateHome, action) {
    switch (action.type) {
    case ADD_SOME_OME:
        return { ...state, home: action.number }  
    default:
        return state
    }
}

function cart (state = initialStateHome, action) {
    switch (action.type) {
    case GET_CART_NUMBER:
        return { ...state, cart: action.number }  
    default:
        return state
    }
}

const reducers = combineReducers({
    home,
    cart,
})复制代码



我们根据这个测试案例来分析combineReducers函数:

export default function combineReducers(reducers) {
    /*
    finalReducers的值为
    {
        home:function home(state = initialStateHome, action){...},
        cart:function cart(state = initialStateHome, action){...}
    }
     */
    const finalReducers = reducers
    //finalReducerKeys 的值为: ['home','cart']
    const finalReducerKeys = Object.keys(finalReducers)

    /*
    这里假设调用了  
    store.dispatch({
        type: 'ADD_SOME_OME',
        number: 30
    })
     */
    return function combination(state = {}, action) {
        /*
        此时 action = {type: 'ADD_SOME_OME',number: 30}
            state 的值应该为: {home:10,cart:20}
        */
        let hasChanged = false
        const nextState = {}
        for (let i = 0; i < finalReducerKeys.length; i++) {
            const key = finalReducerKeys[i]
            const reducer = finalReducers[key]
            const previousStateForKey = state[key]
            /*
            这里会匹配到 type: 'ADD_SOME_OME' 也就 home 函数里面的 switch 语句
            匹配之后会得到的值为:nextStateForKey = {home:30}
            而此时的            previousStateForKey = 10
            */
            const nextStateForKey = reducer(previousStateForKey, action)
            //给nextState 赋值  也就是: nextState['home'] = {home:30}
            nextState[key] = nextStateForKey
            //很明显 nextStateForKey !== previousStateForKey 值为 true
            hasChanged = hasChanged || nextStateForKey !== previousStateForKey
        }
        //因此取 nextState 
        return hasChanged ? nextState : state
    }
}复制代码



这段代码很好理解,你也可以查看我github源码中 mean-combineReducers.js,和combineReducers.js 有可运行的测试案例,有详细的代码说明。

备注:理解此段代码需要理解透createStore.js, 其中以下代码需要注意到,最终会在这里调用:



接下来我们进入到redux的高阶方法 applyMiddleware

redux v3.7.2源码解读与学习之 applyMiddleware


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值