原理
const combineReducer = (state = {}, action) => {const newState = {loginUser: loginUser(state.loginUser, action),users: users(state.users, action)};return newState;}
作用: 组装reducers,返回一个reducer,数据使用一个对象表示,对象的属性名与传递的参数对象保持一致
import isPlainObject from './untils/isPlainObject'import ActionTypes from './untils/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 obect')}for (const key in reducers) {if (Object.hasOwnProperty.call(reducers, key)) {const reducer = reducers[key];let state = reducer(undefined, {type: ActionTypes.INIT()})if (state === undefined) {throw new TypeError('reducers must not return an undefined')}state = reducer(undefined, {type: ActionTypes.UNKNOWN()})if (state === undefined) {throw new TypeError('reducers must not return an undefined')}}}}export default function (reducers) {validateReducers(reducers);return function (state = {}, actions) {const newState = {}; // 返回新状态for (const key in reducers) {if (Object.hasOwnProperty.call(reducers, key)) {const reducer = reducers[key];newState[key] = reducer(state[key], actions)}}return newState;}}
/**** @param {*} obj 对象* @returns 判断是否是平面对象*/function isPlainObject(obj) {if (typeof obj !== 'object') {return false;}return Object.getPrototypeOf(obj) === Object.prototype;}export default isPlainObject
/**** @param {*} length*/function RandomStr(length) {return Math.random().toString(36).substr(2, length).split('').join('.')}export default {INIT() {return `@@redux/INIT${RandomStr(6)}`},UNKNOWN() {return `@@redux/PROBE_UNKNOWN_ACTION${RandomStr(6)}`}}
- INIT和UNKNOWN是combineReducer用来检测子reducer不会返回undefined值,而默认触发的两个特殊的action
for (const key in reducers) {if (Object.hasOwnProperty.call(reducers, key)) {const reducer = reducers[key];let state = reducer(undefined, {type: ActionTypes.INIT()})if (state === undefined) {throw new TypeError('reducers must not return an undefined')}state = reducer(undefined, {type: ActionTypes.UNKNOWN()})if (state === undefined) {throw new TypeError('reducers must not return an undefined')}}}
