原理
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')
}
}
}