Redux-实现combineReducers

最近在读Redux源码,现将自己实现的代码和理解贴上,后期再补充详细~

由于在大中型项目中,操作比较复杂,数据结构也比较复杂,因此,需要对reducer进行细分。redux提供了方法,可以帮助我们更加方便的合并reducer,combineReducers会合并reducer,得到一个新的reducer,该新的reducer管理一个对象,该对象中的每一个属性交给对应的reducer管理。

代码很简单,组装reducers,返回一个reducer,数据使用一个对象表示,对象的属性名与传递的参数对象保持一致,主要是需要对传入的reducer进行检验:

import isPlainObject from "./utils/isPlainObject";
import ActionTypes from "./utils/ActionTypes";

function validateReducers(reducers) {
    if (typeof reducers !== "object") {
        throw new TypeError("reducers must be an object");
    }
    if (!isPlainObject(reducers)) {
        throw new TypeError("reducers must be a plain object");
    }
    //验证reducer的返回结果是不是undefined
    for (const key in reducers) {
        if (reducers.hasOwnProperty(key)) {
            const reducer = reducers[key];//拿到reducer
            //传递一个特殊的type值
            
            let state = reducer(undefined, {
                type: ActionTypes.INIT()
            })
            // null不绝对等于undefined
            if (state === undefined) {
                throw new TypeError("reducers must not return undefined");
            }
            // 再次判断是否返回undefined
            state = reducer(undefined, {
                type: ActionTypes.UNKNOWN()
            })
            if (state === undefined) {
                throw new TypeError("reducers must not return undefined");
            }
        }
    }
}

export function combineReducers(reducers) {
    validateReducers(reducers);
    /**
     * 返回的是一个reducer函数
     */
    return function (state = {}, action) {
        const newState = {}; //要返回的新的状态
        for (const key in reducers) {
            if (reducers.hasOwnProperty(key)) {
                const reducer = reducers[key];
                newState[key] = reducer( state[key], action);
            }
        }
        return newState; //返回状态
    }
}

plain-object(平面对象),它的__proto__指向Object.prototype 

/**
 * 判断某个对象是否是一个plain-object
 * @param {*} obj 
 */
export default function isPlainObject(obj) {
    if (typeof obj !== "object") {
        return false;
    }
    return Object.getPrototypeOf(obj) === Object.prototype;

 初始化时调用的action,这里要对传入的reducers做验证,首先是触发INIT类型的action,如果这里返回undefined表示reducer未做默认处理;然后是触发PROBE_UNKNOWN_ACTION类型的aciton,如果这里返回undefined表示reducer占用了init的命名空间

/**
 * 得到一个指定长度的随机字符串
 * @param {*} length 
 */
function getRandomString(length) { 
    return Math.random().toString(36).substr(2, length).split("").join(".")
}

export default {
    INIT() {
        return `@@redux/INIT${getRandomString(6)}`
    },
    UNKNOWN(){
        return `@@redux/PROBE_UNKNOWN_ACTION${getRandomString(6)}`
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值