这是一个系列文章,旨在分享在react及相关技术栈实践过程当中的我的感悟,心得。若是有很差的地方,欢迎各位批评指正。react
因为对react自己还未深刻了解,今天咱们先来谈一谈redux相关的问题。webpack
Dan Abramov是redux
的做者,同时,他也是Create React App
, React Hot Loader
做者。固然1年前,他也因为redux
及相关的开源贡献加入了facebook
(他大二就辍学了,以前还当过.net工程师)。git
在我最初了解到他的时候,我以为他很是有礼貌。同时,也为了更多的了解redux
,我计划开始阅读他的每一条tweet,原先计划的是从15年7月开始,后来由于进展缓慢,并且react
版本也已经发生很大变化了,因而便从16年1月1日开始阅读,目前记录到7月15日了。事实也证实,在这个过程当中,的的确确学习到了不少东西。包括redux
的文档及redux-links
的做者Mark Erikson,以及国外不少写过redux
系列的朋友们。程序员
若是你有兴趣的话,能够看看我摘录的一些片断。其中除了知识性的内容外,还有一些关于它本身生活,经历,学习方法,如何面对JS疲劳等等的摘录。也让我渐渐的了解到了国外的程序员们的一些观点,兴趣,梗等等。github
好了,暂时先介绍到这里了。切回redux自己,下面是学习源码过程当中本身的一些体会。web
createStore
的第3个参数为enhancer
,若是enhancer
有多个,那么应该使用compose
的方式组合多个enhancer
数据库
且每一个enhancer
的模板为export default createStore => (reducer, preloadedState, enhancer) => {...}
redux
由于在createStore
中执行了:return enhancer(createStore)(reducer, preloadedState)
性能优化
另外,上面的提到的形如(reducer, preloadedState, enhancer) => {...}
这个样子的其实均可以叫作createStore
网络
这也是社区有那么多enhancer
的缘由,他们能够造成一个enhancer
链,我调用你的createStore
,而后返回个人createStore
供下一级调用
因此在本身的createStore
的函数体中常常能看到诸如var store = createStore(reducer, preloadedState, enhancer);
这样的用法,目的就是让本身这一级以前的enhancer
产生一个store
出来,而以前的enhancer
里的createStore
又会调用以前的,到最尽头,就是redux
自己的createStore
applyMiddleware
的目的是返回一个enhancer
,这个enhancer
存储了1个或者多个中间件,中间件在上一级的dispatch
方法的基础上增添本身的逻辑,而后返回本身的dispatch
方法
对于中间件而言,中间件的模板为:export default store => next => action => {...}
。有的地方也写成export default _ref => next => action => {...}
或者export default ({getState, dispatch}) => next => action => {...}
,看本身喜爱了
实际的调用顺序以下(定义在redux
的applyMiddleware.js
中):
1. middleware(middlewareAPI); /* var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) }; chain = middlewares.map(middleware => middleware(middlewareAPI)); dispatch = compose(...chain)(store.dispatch); 第1步即为第1次执行中间件,用redux本身的dipatch初始化各个中间件里的dispatch(也就是中间件的next参数)和getState。 从而确保至少redux自己可以正常工做,中间件的store或者_ref即为这里的middlewareAPI * */ 2. dispatch = compose(...chain)(store.dispatch); /* 第2步即为第2次执行中间件 即用compose的形式链式调用第1步返回的中间件集合,若是中间件是定义在applyMiddleware的最后一个 那么中间件里的next为store.dispatch,不然next为上一个中间件返回的结果,能够理解为上一个中间件 返回的是封装了dispatch的本身的dispatch,这里的原理其实和enhancer如出一辙 enhancer的目的是封装屡次createStore并用compose的方式进行调用 middleware的目的是封装屡次dispatch并用compose的方式进行调用 * */ 总结: /* 因此最后在redux的createStore.js中return的enhancer(createStore)(reducer, preloadedState)的结果就是一个加强 版的store,而这个加强版的store中存放的是加强版的dispatch * */ /* ××××××××××××××××关于combineReducers××××××××××××××× * 从执行上来讲,combineReducers实际上最后就是变成对reducers进行深度优先遍历并执行的过程 * 从结构上来讲,combineReducers决定了咱们的state状态树的最终结构或者说形状,他是呈一个树型结构的 * combineReducers(reducerA, reducerB),reducerA里面嵌套combineReducers(reducerA-child1, reducerA-child2) * 实际上对应状态树而已就是第一层有两个节点A,B,而A节点下面有两个子节点A-child1,A-child2 * * 因此在最初设计的时候,咱们要设想咱们最终的状态树的样子,而后合理划分reducer,就像设计数据库的表结构同样。 固然这是比较归纳的说法,事实上reducer的设计或者说state的划分有太多太多值得研究的东西,这个咱们之后再谈了。 * */
bindActionCreator
实际就是给actionCreator
外层再添加了一层函数,而这层函数存放了对dispatch
的引用
function bindActionCreator(actionCreator, dispatch) { return (...args) => dispatch(actionCreator(...args)) }
因此咱们能够通常在组件里直接调用bindActionCreator
返回的actionCreator
,即this.props.loadSomething(...)
。而不用写成dispatch(actionCreator(...args))
,实际上他们是等价的
既然提到了redux
,因为目前我是采用react
进行开发,因此不得不提到相关的react-redux
。其中最重要的莫属于connect
这个函数了。
传入connect
的组件在挂载到页面上后会调用store.subscribe
进行订阅,订阅的目的是咱们调用dispatch
的时候,代表咱们的状态树即将发生变化,这个时候咱们但愿咱们的组件对应发生变化,而组件变化的惟一方式就是setState
。
订阅就是告诉redux
,这个组件是依赖于状态树的某部分工做的,因此当你变化的时候,记得获取最新的state
,而后通知我,至于我如何响应,那就是我本身的事了,你只管通知我状态树发生了变化并把它传给我就好了。值得一提的是,connect
内部进行了大量的性能优化,避免没必要要的渲染,关于此以及mapStateToProps
和mapDispathToProps
,咱们放到之后再谈。
篇幅有限,这一篇文章暂时就先这样啦,更多的内容,我想放在下一篇来分享,同时本身也在不断学习,但愿能理解得更好。
值得一提的是,咱们也许会认为咱们了解到的redux,mobx,rxjs等等彻底不一样理念的库,他们的做者也许也是"极端"的,是排斥他人及理念的。实际上,这是不正确的,早在16年5月,Dan就和mobx的做者在twitter上有过互动,他们达成了共识,那就是和对方一块儿合做,一块儿推进自身以及react的发展。
对于redux-thunk,文档中也许会首先建议使用这个简单的库来处理异步相关的问题。对于复杂的应用,他们也推荐使用redux-saga这样的库去重构本身的代码。在twitter上,Dan也屡次提到过库的应用场景的问题,建议你们用以前先了解本身为何要使用,它解决了哪些痛点,而后再去使用。甚至特地提过issue,来了解react-router-redux的做用。
除此以外,也提到在时间充裕的状况下,学习react,应该先从自己入手,ES6,webpack,jsx,redux等等和react自己都是没有直接联系的,在学习完react以后,咱们知道了他自己的哪些不足,哪些地方须要增强,哪些地方须要引入第三方库去解决,解决的是哪些痛点,咱们再去了解这些工具,才能真正体会到他们的威力。
说到这里,稍微有一点远了,不过我以为仍是有必要说起一下。那就是,咱们身处一个浮躁的社会,不管是在现实中对待朋友,亲人,陌生人,因为学习,工做,生活的压力,周遭的浮躁氛围的影响,多多少少也会让本身带着些许暴戾之气。在网络上,因为约束的放宽,咱们也许更会将压抑的情感释放给广袤的网络世界,在微博,贴吧,知乎上,咱们或多或少书写着,察觉着这样的行为。
可是,做为一名程序猿,我仍是期待可以看到咱们这个圈子更多的将时间,精力,努力花费在对现有技术的改进,对未知世界的探索,追寻程序,库,框架,思想的本质,结交志同道合的朋友,一块儿交流,分享,思考对技术的见解。而不是卷入无休止的撕逼,用了某某而产生的优越,甚至借贬低他人来抬高本身。
咱们能够理解一时的愤懑之情,由于咱们大多,真是只是普普统统的社会人,喜怒哀乐再日常不过。但若咱们一直保持这种状态,永远在上面这些场景都留下对人不对事的话语,讥讽,甚至谩骂。但愿你们能为咱们的后代想一想。