前端的浪潮一叠叠袭来,带走了jQuery,带走了backbone,带来了react,带来了redux,但是面对层出不穷的前端技术,我们应该何去何从呢?近一年来笔者的也发生了同样的变化,技术栈从.net+backbone+requirejs+grunt变成了nodejs+react+webpack+gulp,一系列的变化也让笔者对整个过程,整个闭环的工具链有了一些自己的感受和理解,于是有了今天此文。

  其实react出现得很早,但是笔者所在的唤作“大象转身”的大公司,所以内部技术的迭代,并不像业务迭代那么的频繁,毕竟大多数公司奉行的依旧是技术为业务服务的原则(诚然,技术没有经济利益的产出,则没有理由不信奉,不过这又是另一个话题,权且按下不表)。不过也就在去年,笔者由于一些工作上的变动,开始全面的接触起了react起来,于是念上心头,我们为什么要用react呢?

  其实,谈到react,可能最先映入眼帘的就是它对于dom的托管,virtual dom技术的出现也一定程度上封装了之前纷繁复杂的dom操作,而且也降低了使用门槛(有关浏览器内部渲染原理),虽然这也是有副作用的,但是它相较于backbone,省去了大量的dom交互的过程,对于每位前端er都是一件很了不起的事情;不过,相比之下,笔者其实更中意它的设计中的数据流的思想,数据能够受到约束之后,页面的状态不再像之前的时代那么混乱无序,一切归于平静是多么美好的一件事情。。但是,这种好日子其实并不长久,在应付小规模应用的时候,有约束的数据流向和传输也许并没有什么副作用,但是项目规模扩大之后,一级一级的状态/属性传输却显得特别的臃肿和低效,如下图:

  

  当我们的组件树只有1层或者2层的时候,想从最上层透传属性还是很容易的事情,但是当组件层级越来越多,比如上图,从底层父组件传递属性到达最末的叶子组件,整个过程的传输在代码上就显得相当的冗余,而且如果多个组件依赖于一个共同的属性,局部变化引起的全局变化很容易又会导致状态震荡,这也是令人倍感头疼的问题,所以redux就应运而生。

  react官方最先推出的方案是flux,随后见贤思齐的将其替换为了redux。其实react中强调的单向数据流几乎是需要依托redux才能实现的,当接入了redux之后,整个数据流动就变成了以下这个样子:

  

  所有的状态变化都拘束到reducer(s)中进行,修改统一的数据源,然后再自上而下的重新分发,减少状态/属性传递的成本,也从根源上杜绝了状态震荡,而且redux将数据从react中分离,则理论上所有的react component都可以是无状态组件,那么渲染性能还能够得到进一步的提升。

  看到这么精巧的设计,笔者饶有兴致的研究了一下源码,并且尝试着自己也实现了一个简单的redux,其实redux的源码也非常的简洁:

index.js
createStore.js
compose.js
combineReducers.js
bindActionCreators.js
applyMiddleware.js

  主要文件一共就6个,用得最多的就是createStore和引用了职责链模式的applyMiddleware,createStore中大量的体现了函数式编程的思想,刚开始读起来确实有些吃力,而且js似乎并不是一个很好的实现函数式编程的语境,不过瑕不掩瑜,短短百行不到的代码,却解决了react没能解决的一个很棘手的问题,这也确实是令人惊讶的;另外,相信使用过koa的同学对于职责链模式其实并不陌生,特别是还看到了那个蜜汁compose,那种剥洋葱的调用结构极大的提高了我们在nodejs 写webservice时的扩展性,也跟我们后续的维护提供了一定的便利。

  不过本文意并不在介绍它们的内部原理,让我们回到正题。说了一大堆redux的优点,那么它有没有缺点呢?诚然,事无绝对,必有正反。虽然redux提供了很大的方便也弥补了react的一些机制不足,在技术方案上,似乎并没有什么问题,但是在实际使用时,由于它自身的松散耦合的特性,导致了实现具体功能时多种多样的方式,而不同的人的理解又会导致不同的实现,举两个笔者所在的团队的例子:

  一个是有关数据统计和异步请求的代码究竟应该写在哪的问题。不同的业务场景不同的人,不同的实际情况,很有可能会让我们在实际操作时,将action和reducer混淆使用,这样本来是为了降低维护成本而剥离产生的action却增加了我们的额外成本,这其实是得不偿失的。

  另一个是关于状态注入时状态的多少问题。注入少了,之后的需求变更又需要频繁改变代码,注入多了又会导致组件的频繁更新,且注入方式相当的随意,对后续维护也是一件非常吃力的事情。。。

  其实这样的例子还有很多,归根结底redux是一种思想,而且还是一种很灵活的思想,它给了使用者很大的自由发挥的空间,但是在社会化的协同工作时,过多的“自由”却又意味着“不自由”。 

  其实时代的变迁,历史的演进,新旧事物的交替其实是提现了人类思维方式的变化和面对的场景的变化。当初我们只需要dom操作就能完成页面,所以jQuery就足够了,但是现在随着前端的不断发展,体验要求、功能要求越来越高,越来越多,原始的简单页面维度的应用已经不能满足了,于是,react或者其他的类virtual库才会应运而生,然后新问题出现了,再去造新的轮子,然后,历史也便形成了。

  但我们仔细想来,就会发现,我们所造之物,其实永远都不是一个囊括所有问题答案的方案,我们给出的,不过是针对某一个历史时期的某一个场景的某一个局部最优解而已,问题在变化,答案也在变化,不变的,也许只有时间亘古不变的流逝,以及我们那颗需要永远保持运动变化的心。

  

【js】为什么要使用react+redux的更多相关文章

  1. Immutable.js 以及在 react+redux 项目中的实践

    来自一位美团大牛的分享,相信可以帮助到你. 原文链接:https://juejin.im/post/5948985ea0bb9f006bed7472?utm_source=tuicool&ut ...

  2. webpack+react+redux+es6开发模式

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

  3. react+redux教程(六)redux服务端渲染流程

    今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...

  4. react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

    今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...

  5. 基于React,Redux以及wilddog的聊天室简单实现

    本文主要是使用ReactJs和Redux来实现一个聊天功能的页面,页面极其简单.使用React时间不长,还是个noob,有不对之处欢迎大家吐槽指正. 还要指出这里没有使用到websocket等技术来实 ...

  6. react+redux教程(四)undo、devtools、router

    上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...

  7. react+redux教程(三)reduce()、filter()、map()、some()、every()、...展开属性

    reduce().filter().map().some().every()....展开属性   这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https:// ...

  8. react+redux教程(一)connect、applyMiddleware、thunk、webpackHotMiddleware

    今天,我们通过解读官方示例代码(counter)的方式来学习react+redux. 例子 这个例子是官方的例子,计数器程序.前两个按钮是加减,第三个是如果当前数字是奇数则加一,第四个按钮是异步加一( ...

  9. angular开发者吐槽react+redux的复杂:“一个demo证明你的开发效率低下”

    曾经看到一篇文章,写的是jquery开发者吐槽angular的复杂.作为一个angular开发者,我来吐槽一下react+redux的复杂. 例子 为了让大家看得舒服,我用最简单的一个demo来展示r ...

  10. 【原】react+redux实战

    摘要:因为最近搞懂了redux的异步操作,所以觉得可以用react+redux来做一个小小的项目了,以此来加深一下印象.切记,是小小的项目,所以项目肯定是比较简单的啦,哈哈. 项目效果图如图所示:(因 ...

随机推荐

  1. Codeforces Educational Round 23

    A emmmmmmmmm B emmmmmmmmm C(套路) 题意: 给定n和s(n,s<=1e18),计算n以内有多少个数x满足(x-x的各个位置数字之和)>=s 分析: 容易想到如果 ...

  2. ArcGIS for Android离线数据编辑实现原理

    来自:http://blog.csdn.net/arcgis_mobile/article/details/7565877 ArcGIS for Android中现已经提供了离线缓存图片的加载功能,极 ...

  3. 【python自制】让大白成为你的个人助手!

    我做这个软件就是要让卖萌进行究竟! 官方站点:http://www.jackeriss.com/companions.htm GitHub:https://github.com/Jackeriss/C ...

  4. [TypeScript] Use TypeScript’s never Type for Exhaustiveness Checking

    TypeScript 2.0 introduced a new primitive type called never, the type of values that never occur. It ...

  5. hdu 1565 方格取数(1)(状态压缩dp)

    方格取数(1)                                                                 Time Limit: 10000/5000 MS (J ...

  6. 连通分量模板:tarjan: 求割点 &amp;&amp; 桥 &amp;&amp; 缩点 &amp;&amp; 强连通分量 &amp;&amp; 双连通分量 &amp;&amp; LCA(近期公共祖先)

    PS:摘自一不知名的来自大神. 1.割点:若删掉某点后.原连通图分裂为多个子图.则称该点为割点. 2.割点集合:在一个无向连通图中,假设有一个顶点集合,删除这个顶点集合,以及这个集合中全部顶点相关联的 ...

  7. 抢占式内核与非抢占式内核中的自旋锁(spinlock)的差别

    一.概括 (1)自旋锁适用于SMP系统,UP系统用spinlock是作死. (2)保护模式下禁止内核抢占的方法:1.运行终端服务例程时2.运行软中断和tasklet时3.设置本地CPU计数器preem ...

  8. android不是内部或外部命令,也不是可执行的程序或批处理文件

    问题: 原因:没有配置好android sdk环境变量 解决方法: (1)切换到android sdk下的tools文件夹,再执行android命令就可以启动Android SDK管理器,我的andr ...

  9. TQ2440 学习笔记—— 1、Windows平台下开发工具安装与环境建立

    板子:广州天嵌公司的TQ2440,处理器为三星的S3C2440 1.开发工具的安装与环境建立 系统:win7  64位 SecureCRT软件:该软件能够取代Windows中的超级终端,是个非常好的串 ...

  10. TensorFlow的安装与CNN测试

    0.说明 在Google开源该框架之后便使用真实K40m卡测试,由于生产环境是CentOS6.6的操作系统,但是该框架需要在Python2.7环境下执行,CentOS6.6下折腾了一天没搞定,后来换成 ...