Open ihtml5 opened 8 years ago
项目的源代码,包括以下几个文件: index.js 整个redux框架的入口文件 作用: 导出redux的几大函数包括createStore,bindActionCreators,combineReducers,compose,applyMiddleware createStore.js 创建应用唯一的state树 bindActionCreators.js 工具类函数 作用: 方便开发者将dispatch和actioncreator当props绑定到组件中 combineReducers.js 将多个reducer,合并成一个reducer,传入到createStore函数中 compose.js 将多个函数组合执行 applyMiddleware 工具类函数 作用: 将中间件如redux-thunk应用到createStore函数上 util/warning.js 自定义的错误信息提示函数 2.docs redux的文档. 官方网站:www.redux.js.org 中文翻译:cn.redux.js.org 3.build 构建redux所需要的一些文件 4.examples redux的使用案例,从简单的原生counter到复杂到真实场景的应用,都提供了案例参考 5.test 测试文件目录 6.node_modules redux源码所依赖的node包
项目的源代码,包括以下几个文件:
整个redux框架的入口文件 作用: 导出redux的几大函数包括createStore,bindActionCreators,combineReducers,compose,applyMiddleware
创建应用唯一的state树
工具类函数 作用: 方便开发者将dispatch和actioncreator当props绑定到组件中
将多个reducer,合并成一个reducer,传入到createStore函数中
将多个函数组合执行
工具类函数 作用: 将中间件如redux-thunk应用到createStore函数上
自定义的错误信息提示函数
redux的文档. 官方网站:www.redux.js.org 中文翻译:cn.redux.js.org
构建redux所需要的一些文件
redux的使用案例,从简单的原生counter到复杂到真实场景的应用,都提供了案例参考
测试文件目录
redux源码所依赖的node包
源代码使用了es6语法,使用import关键词从文件中导出模块 源码解读
源代码使用了es6语法,使用import关键词从文件中导出模块
export { createStore, compose, warning, combineReducers, bindActionCreators }
关键词
export default javascript中异常处理 javascript中错误处理 阮一峰谈javascript错误处理
源码解读
1.判定console.error是否存在且可用
// 导出warning函数 export default function warning(message) { // 判断console.error函数是否存在且可用 if (typeof console !== 'undefined' && typeof console.error == 'function') { console.error(message); } }
2.捕获异常并处理
try { // 抛出异常 throw new Error(Message) } catch(e) { // 捕获异常 }
[闭包]()
var reducers = { reducer1:reducer, reducer2: reducer} 辅助对象导出部分: import { ActionTypes } from './createStore'; import isPlainObject from 'lodash/isPlainObject'; import warning from './utils/warning' 辅助函数定义部分 getUndefinedStateErrorMsg(key,action) 何时用: 当reducer(previousState,action) === undefined时,调用这个函数,给予用户一定警告。 返回结果: 告诉用户你当前没有给reducer一个初始值,你必须显式的指明初始值 getUnexpectedStateShapeWarningMessage(inputState,reducers, action) 何时用: 检测输入的inputState是否和reducers对应 原理: 首先检测inputState必须是个对象,reducers是否有效(检测reducers对应的key数组是否长度大于1),inputState中的key是否完全包含在reducers的key中,如果以上几种情况有任一一种不满足情况,函数都会停止执行,并返回相应的错误信息提示. assertReducerSanity(reducers) 何时用: 判断输入reducers对象中给定reducer是否有效 原理: 将reducers对象中的reducer进行分别测试,如下: javascript var initialState = reducer(undefined,{type: ActionTypes.INIT}); var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.'); typeof reducer(undefined, { type } === 'undefined') /* 如果给定的reducer在初始化或者给定的action的type是一个'@@redux/PROBE_UNKNOWN_ACTION'开头的随机类型时,返回值为undefined,则 直接扔出异常,证明其传入的reducer不符合要求,需要检查核对,重新修改。 */ 核心 combineReducers函数详解 初步筛选 终于到了分析combineReducers的时候了,该函数最终返回回来一个rootreducer,形式如 rootReducer(state= {},action);在返回这个根reducers函数前,进行了两部分的工作, 将参数reducers进行过滤,初步筛选出类型为function的reducer并存入finalReducers对象中,相关代码如下:
var reducers = { reducer1:reducer, reducer2: reducer}
import { ActionTypes } from './createStore'; import isPlainObject from 'lodash/isPlainObject'; import warning from './utils/warning'
javascript var initialState = reducer(undefined,{type: ActionTypes.INIT}); var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.'); typeof reducer(undefined, { type } === 'undefined') /* 如果给定的reducer在初始化或者给定的action的type是一个'@@redux/PROBE_UNKNOWN_ACTION'开头的随机类型时,返回值为undefined,则 直接扔出异常,证明其传入的reducer不符合要求,需要检查核对,重新修改。 */
终于到了分析combineReducers的时候了,该函数最终返回回来一个rootreducer,形式如 rootReducer(state= {},action);在返回这个根reducers函数前,进行了两部分的工作, 将参数reducers进行过滤,初步筛选出类型为function的reducer并存入finalReducers对象中,相关代码如下:
var reducerKeys = Object.keys(reducers) var finalReducers = {} for (var i = 0; i < reducerKeys.length; i++) { var key = reducerKeys[i]
if (process.env.NODE_ENV !== 'production') { // 开发环境下,判断reducer是否未定义 if (typeof reducers[key] === 'undefined') { warning(`No reducer provided for key "${key}"`) } } // 当reducer类型为function的时候,才存入finalReducers对象中 if (typeof reducers[key] === 'function') { finalReducers[key] = reducers[key] }
}
传入的reducer有效性验证
if (process.env.NODE_ENV !== 'production') { // 如果是开发环境,检测是否传入了不恰当的key var unexpectedKeyCache = {} } /* 对初步筛选出来的finalReducers进行有效性检测,除了要求reducer是函数外, 还需满足assertReducerSanity,否则抛出异常,程序终止 */ var sanityError try { assertReducerSanity(finalReducers) } catch (e) { sanityError = e }
返回根reducer
return function combination(state = {}, action) { // reducers中有reducer无效,程序就会抛出异常 if (sanityError) { throw sanityError } if (process.env.NODE_ENV !== 'production') { // 开发环境下,检测给定的state,finalReducers是否对应,如果不对应,就会抛出异常 var warningMessage = getUnexpectedStateShapeWarningMessage( state, finalReducers, action, unexpectedKeyCache) if (warningMessage) { warning(warningMessage) } } var hasChanged = false var nextState = {} // finalReducers如何合成根state for (var i = 0; i < finalReducerKeys.length; i++) { var key = finalReducerKeys[i] var reducer = finalReducers[key] var previousStateForKey = state[key] var nextStateForKey = reducer(previousStateForKey, action) if (typeof nextStateForKey === 'undefined') { var errorMessage = getUndefinedStateErrorMessage(key, action) throw new Error(errorMessage) } nextState[key] = nextStateForKey hasChanged = hasChanged || nextStateForKey !== previousStateForKey } return hasChanged ? nextState : state }
一.目录分析
1.src
二.源码分析
1.src/index.js
2.src/utils/warning.js
关键词
源码解读
1.判定console.error是否存在且可用
2.捕获异常并处理
3.src/combineReducer.js
关键词
源码解读
var reducerKeys = Object.keys(reducers) var finalReducers = {} for (var i = 0; i < reducerKeys.length; i++) { var key = reducerKeys[i]
}
传入的reducer有效性验证
返回根reducer
相关链接