首页 > 代码库 > 【js】为什么要使用react+redux

【js】为什么要使用react+redux

  前端的浪潮一叠叠袭来,带走了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