reactYes? 处理数据流?

为what数据流管理如此重要?react的核心思想就是:UI=render(data),data就是We说的数据,render是reactprovide的纯函数,所以user界面的展示完全取决于数据层。

this篇文章hope能用最浅显易懂的话,takereact中的数据流管理,从自身到借助第三方库,takethis些概念理清楚。我会列举几个当下最热的库,包括它们的思想以及优缺点,适用于Which业务场景。

this篇文章不是教程,不会讲how 去使用它们,更不会一言不合就搬源码,正如文章标题所说,只是浅谈,hope读者stay读完以后就算原让挥惺褂霉齮his些库,也能大致有个思路,know 该how choice性地深入学习。

stay本文正式start之前,我先试图讲清楚两个概睿状态和数据

We都know ,react是利用可复用的组件来构建界面的,组件本质上是一个有限状态机,它能够记住当前所处的状态,also能够根据不同的状态变化做出相应的操作。stayreact中,把this种状态定义为state,用来描述该组件对应的当前交互界面,express当前界面展示的一种状况,react正是通过管理状态来实现对组件的管理,当state发生变更时,react会自动去执行相应的操作:绘制界面。

所以We接下来提到的状态是in the light ofreact componentthis种有限状态机。而数据就广泛了,它不光是指server层返回给前端的数据,react中的状态So is it一种数据。当We改变数据的同时,就要通过改变状态去initiation界面的变更。

We真正要care for的是数据层的管理,We今天所讨论的数据流管理programme,特别是后面introduce的几种第三方库,不光是配合react,也sure配合其他的View框架(Vue、Angular等等),就好比开头提到的那个公式,引申一下:UI =X(data),但今天main是围绕react来讲的,thereforeWestay说react的状态管理actually和数据流管理是一样的,包括We会借助第三方库来帮助react管理状态,hope不要有小伙伴太纠结于此。

一、react自身的数据流管理programme

We先来回顾一下,react自身是how 管理数据流的(也sure理解为how 管理应用状态):

react是自上而下的单向组件数据流,容器组件&展示组件(步猩倒献榧&聪明组件)是最常用的react组件设计programme,容器组件be responsible for处理复杂的业务逻辑以及数据,展示组件be responsible for处理UI层,通常We会take展示组件抽出来进行复用或者组件库的封装,容器组件自身通过state来管理状态,setStateto update状态,从而to updateUI,通过propstake自身的state传递给展示组件实现通信。

this是当业务需求不复杂,page面较简单时We常用的数据流处理方式,仅用react自身provide的props和state来管理足矣,howeverif稍微增加一点复杂度呢,比如当We项目中遇到this些problem:

1)how 实现跨组件通信、状态同步以及状态共享?

react V16.3以前,通过状态提升至最近的共同父组件来实现。(虽然有officialprovide的contextAPI,however旧版本存stay一个problem:此瓶缱榧翟騭till逐级传递,if中间组件使用了ShouldComponentUpdate检测到当前state和props没有变化,returnfalse,那么context就会无法透传,thereforecontext没有被official推荐使用)。

1.jpg

react V16.3版本以后,新版本context解决了之前的problem,sure轻松实郑但依然存stay一个problem,contextSo is ittake底部子组件的状态控制交给到了顶级组件,however顶级组件状态to update的时候一定会触发All子组件的re-render,那么也会带此鸷摹#虽然Wesure通过一些手段来减少重绘,比如stay中间组件的SCU里进行一些判断,however当项目较大时,We需要花太多的精力去做this件事)

2.jpg

2)how 避免组件臃肿?

当某个组件的业务逻辑very复杂时,We会find 代码越写越多,becauseWe只能stay组件内部去控制数据流,没办法抽离,Model和View都放stay了View层,整个组件显得臃肿不堪,业务逻辑统统堆stay一块,难以维护。

3)how 让状态变得可预知,even to the extent that可回溯?

当数据流混乱时,We一个执行actionprobably会触发一系列的setState,Wehow 能够让整个数据流变得可“监控”,even to the extent thatsure更细致地去控制每一步数据或状态的变更?

4)how 处理异步数据流?

react自身并未provide多种处理异步数据流管理的programme,仅用一个setState已经很难满足一些复杂的异步流场景;

how 改进?

this个时候,Weprobably需要一个真正的数据流管理工具来帮助react了,Wehope它是真正脱离react组件的概念的,从UI层完全抽离出来,只be responsible for管理数据,让react只专注于View层的绘制。

那thisSo is it为whatWe需要使用those 第三方数据流管理工具的reason ,接下来We就来了解一些当前社区比较让诺氖据流管理工具。

二、redux

我直犹薴lux此祌edux,main是becauseredux是由flux演变而来,sure说是flux的upgrade加强版,flux具备的优势redux也做到了。

reduxprovide了Which?

3.jpg

1)store:provide了一个全局的store变量,用来存储Wehope从组件内部抽离出去的those 公用的状态;

2)action:provide了一个普通对象,用来记录We每一次的状态变更,可日志打印与调试回溯,alsothis是唯一的途径;

3)reducer:provide了一个纯函数,用来计算状态的变更;

为what需要redux?

很多人stay用了一段time的redux之后,最大的感想就是,redux要写大量的模板代码,很麻烦,还不如只用react来管理。特别是stayreact男耤ontext推出以后,许多人更是直接弃用了redux,even to the extent that觉得redux已死。if说旧版的context的弊端,We通过redux配合react-redux来实现跨组件的状态通信同步等problem,那确实新版本的contextsure替换掉this个功能点,但if你的项目中仅仅是用redux做this些,那思家幌拢闶欠真男枰猺edux?也许从一start你就不需要它。

(虽然新版的context功能强大,however依然是通过一个新的容器组件来替We管理状态,那么通过组件管理状态的problem依旧会存stay,Consumer是和Provider一一对应的,stay项目复杂度较高时,probably会出现多个Provider,more个Consumer,even to the extent that会一个Consumer需要对应多个Provider的传值等一系列复杂的情况,所以We依然要谨慎使用)

redux的核心竞争力

1)状态持久化:globalstoresure保证组件就算销毁了也依然保留之前状态;

2)状态可回溯:每个action都会被序列化,Reducer不会修改原有状态,总是返回新状态,奖阕鲎刺厮荩

3)Functional Programming:使用纯函数,输出完全依赖输入,没有任何副effect;

4)中间件:in the light of异步数据流,provide死鄀xpress中间件的模式,社区也出现了一大批优秀的第三方插件,能够更精细地控制数据的流动,对复杂的业务场景起到了缓冲地effect;

4.jpg

与其说是redux来帮助react管理状态,不如说是takereact的部分状态移交至redux那里。redux彻头彻尾的纯函数理念捅砻髁怂换岵斡肴何状态变化,完全是由reactown来完成。只howeverredux会provide一套工具,react照着说明书来操作罢了。

所以this注定了想要acceptredux,捅匦按照它的规矩来做,除非你不愿意acceptthis种FP的模式。this种模式有利有弊,有利就是stay一个大型的多人team中,this种开发模式反而easily形成一种规约,让整个状态流程变得清晰,弊端就是对于小规模team,尤其是着急release上线的,this种繁重的代码模板无疑是一指旱!

redux的缺点:

1)繁重的代码模板:修改一个stateprobably要动四五个文件,可谓牵一发而动全身;

2)store里状态残留:多组件共用store里某个状态时要注意初始化清空problem;

3)无脑的release订阅:看蝑ispatch一个action都会遍历All的reducer,重新计算connect,this无疑是一种损耗;

4)交互频繁被嵊锌ǘ伲篿fstore较大时,且频繁地修改store,会明显看到page面卡顿;

5)不supporttypescript;

关于how 优化,网上有很多优秀的案例,reduxofficial也provide了很多方法,this里不再赘述。redux未来不会有太大的变化,those 弊端still会continue保留,howeverthis依然不会妨碍忠爱它的user去使用它。

if说redux那种强硬的函数奖喑棠J让很多人难以accept,那么当theystartmobx的使用的时候,无疑是一种解脱。

三、mobx

最start接触mobxSo is itbecausereduxauthorDanAbramov的那句:Unhappywith redux?try mobx,我believe很多人So is itbecausethis句话而start了解学习并使用它的。

下面列举一些mobx的优势(和redux进行一个对比)

1)redux不市碇苯有薷膕tate,而mobx可随意修改;

2)redux修改状态必须走一套指定的流程较麻烦,而mobxsurestay任何地方直接修改(非严格模式下);

3)redux模板代码文件多,而mobxvery简洁,就一个文件;

4)redux只有一个store,state orstore难以取舍,而mobx多store,你sure把All的state都放入store中,完全交给mobx来管理,减少顾虑;

5)redux需要对监听的组件做SCU优化,减少重复render;而mobx都是SmartComponent,不用We手动做SCU;

mobx的设计思想:

5.jpg

说了this么多,if你是第一次了解mobx,是不是听着就感觉很爽!you re right,this就是mobx的魅力,那它是how 实现this些功能的呢?

this里以mobx 5版本为例,实际上它是利用了ES6的proxy来追踪属性(旧版本是用Object.defineProperty来实现的)通过隐式订阅,自动追踪被监听的对象变化,then触发组件的UIto update。

if说redux是把要做的事情都交给了user,来保证own的纯净,那么mobx就是把最简易的操作给了user,其它的交给mobx内部去实现。user不必care forthis个过程,Model和View完全分离,We完全suretake业务逻辑写stayaction里,user只需要操作Observabledata就行了。

Observerview会自动做出响应,this就是mobx主打的响应式设计,however编程style依然是传车拿嫦蚨韵蟮腛O范式。(熟悉Vue的friend一定对this种响应式设计不陌生,Vue就是利用了数据劫持来实现双向绑定,actuallyReact +Mobx就是一个复杂点的Vue,Vue 3版本一个重大改变So is ittakeagent交给了proxy)

刚刚mobx的优势说得比较多了,this边再总结一下:

1)代码量少;

2)基于数据劫持来实现精准定位(真正意义上的局部to update);

3)多store抽离业务逻辑(Model View分离);

4)响应式性能良好(频繁的交互依然sure胜任);

5)完全sure替代react自身的状态管理;

6)supporttypescript;

howevermobx真的this么完美吗,of course也有缺陷

1)没有状态回溯能力:mobx是直接修改对象引用,所以很难去做状态回溯;(this点redux的优势就瞬间体现出来了)

2)没有中间件:和redux一样,mobx也没有很好地办法处理异步数据流,没办法更精细地去控制数据流动;(redux虽然own不做,however它provide了applyMiddleware!)

3)store太多:随着store数的增多,维护成本也会增加,and多store之间的数据共享以及相互引用也会easily出错

4)副effect:mobx直接修改数据,和函数奖喑棠J强调的纯函数相反,this也导致了数据的很多未知性

actuallyNow主流的数据流管理分为两大派,一类是以redux为首的函数式库,还有一类是以mobx为首的响应式库,actually通过刚刚的introduce,We会find ,redux和mobx有一个共同的短板,那就是stay处理异步数据流的时候,没有一个很好的解决programme,至少仅仅依靠自身比较eat力,那么接下来给everybodyintroduce一个处理异步数据流的高郑簉xjs。

四、rxjs

我believe很多人听说过rxjs学习曲线异常陡峭,是的,除羢earch刍ㄧ月业母骼嗖僮鞣壳皉xjs V6版本有120+个),关键是它要求Westay处理事务的时候要贯彻“everything皆为流”的理睿让初学者难岳斫狻

this一小节并不能让读者达到能够上手使用的程度,正如文章开头所说,hope读者(新郑┠芏詒xjs有一个新的认知,know 它是做what的,它是how 实现的,它有Which优势,Wehow choice它,if感兴趣还需要私下花大量time去学习掌握various操作符,但我也会尝试尽probably地相对于前两个说得更细致一些。

staystartintroducerxjs之前,We先来简单地聊聊what是响应奖喑蹋我以一个很简单男±永看:a + b = c。

if站stay传车拿钍奖喑痰慕嵌壤看this段公式:c的值完全依赖于a和b,this时候We去改变a的值,那We就需要再去手动计算a + b的值,a、b和c是相互依赖的。

那么if站stay响应奖喑痰慕嵌壤看,this个公式又会变成this样:c := a + b,a和b完全不care forc的值,c也完全不care for等式那边是a或者b,或者还有whatd,e,f。。。等式右边改变值了,左边会自动更改数值,this就是响应奖喑痰乃维方式。

We再来看前端的框架history,传统命令奖喑痰拇恚簀Query,stay过去We是how 绘制一个page面的?We会用jQueryprovide的一套API,then手动操作Dom来进行绘制,很精准,however很累,because完全靠手动操作,且改动时性能损耗较大,开发者的注意力完全stay“how 去绘制”上面了。

那We再来看响应奖喑痰膔eact,它是how 来实现的?

开发者根本不用care for界面how 绘制,只要告诉reactWehopepage面长what样子,就sure了,剩下的交给react,react就会自动帮We绘制界面,还记得开头时的那个核心思想吗:UI =render(data),We只要操作data就sure了,page面UI会自action出响应,andWeeverything的操作都是基于内存之中,不会有较大男阅芩鸷模瑃his就是react响应奖喑痰木瑁琒o is it为何它叫作react。

回到We的rxjs上,rxjs是how 做到响应式的呢?多亏了它两种强大的设计模式:观察者模式和迭代器模式;简单地introduce一下:

1)观察者模式:

6.jpg

stay观察者模式中,有两个重要的角色:Observable和Observer,熟悉mobx的classmate对this个一定不陌生(所以我建议想要学习rxjs的classmate,if对mobx不熟悉,sure先学习一下mobx,then再学习rxjs,this样会更easily理解一些)。

就是可观察对象和观察者,可观察对象(Observable)也就是事件release者,be responsible for产生事件,而观察者(Observer)也就是事件响应者,be responsible for对release的事件作出响应,howeverhow 连接一个release者和响应者呢?

通过订阅男问剑就是subscribe方法(this也类似于redux的store.subscribe),而stay订阅之前,they两者是毫无关联的,无论Observable发出多少事件,Observer也不会做出任何响应,同样,当this种订阅关系中断时也不会。

2)迭代器模式:

staythis里要先引出一个新的概睿豪。╬ull)和推送(push),rxjsofficialthis两种agreement有更详细的解释,我this里就直接引用一下:

7.jpg

拉取和推送实际上对于观察者此就是一个主动与被动的区别,是主动去获取still被动地接收。stayrxjs中,作为事件响应者(消费者)的Observer对象也有一个next属性(回调函数),用来接收从release者那里“推”过来的数据。

(站stay开发者的角度,We一定是hope消息是被动地接收,becauseWe倡导的就是通过操作data数据层,让View层进行一个响应,那么this里data数据层一定是事件release者,而View层就是事件响应者,康眃ata数据层发生变化时,都会主动推送一个值给View层,this欧真正意义上的响应奖喑蹋鴕xjs做到了!)

how 配合react?

if说redux和mobx的出现或多或少是becausereact的存stay,那么不同的是rxjs和react并没有what关联,关于rxjs的historythis里不多说,感兴趣的sure了解一下ReactiveExtension,rxjs只是响应奖喑蘳tayJavaScript中的应用。

那么how 帮助react实现状态管理呢,We只需要take组件作为事件响应者,thenstaynext回调里定义好to update组件状态的actionsetState,当接收到数据推送时,就会自动触发setState,完成界面to update,thisactually有点类似于mobx做的事情。(很多人stayreact项目中并没有完全只使用rxjs,而是用了this个redux-observable中间件,利用rxjs的操作符来处理异步action)

除了响应奖喑痰镊攘Γ瑀xjs还有what优势呢?

1)纯函数:rxjs中数据流动的过程中,不会改变已经存stay的Observable实例,会返回一个新的Observable,没有任何副effect;

2)强大的操作符:rxjs又被称为lodash forasync,和lodash一样,拥有众多强大的操作符来操作数据流,不光是同步数据,特别是in the light ofvarious复杂的异步数据流,even to the extent thatsure多种事件流组合搭配,汇总到黄鸫恚

3)更独立:rxjs并不依赖谌魏我桓隹蚣埽黶ure我獯钆洌琤ecause它的关注点完全就是stay于数据流的处理上,and它更偏底层一些

那rxjs有Which缺点呢?

1)学习曲线陡峭:光是this一点就已经让大多数人止步于此;

2)事件流高度抽象:用rxjs的user反馈commonly都是两种极端情况,用得好的都觉得this个太厉害了,用得不好的都觉得感觉有点麻烦,增加了项目复杂度。

五、结语

最后,总结一下各类的适用场景:

1)当We项目中复杂程度较低时,建议只用react就sure了;

2)当We项目中跨组件通信、数据流同步等情况较多时,建议搭配react男耤ontext api;

3)当项目复杂度commonly时,小规模team或开发周期较短、要求fast速上线时,建议使用mobx;

4)当项目复杂度较高时,team规模较大或要求对事件分发处理可监控可回溯时,建议使用redux;

5)当项目复杂度较高,且数据流(尤其是异步数据)混杂时,建议使用rxjs;

actually回顾全篇,我没有提到一个关键点是,各个库男阅芏员萮ow 。actually它们之间一定是有差斓模琱oweverthis点性能差异,相对于react自身组件设计不当而导致男阅芩鸷睦此担莝ure忽略的。

if你Now的项目觉得性能较差或者page面卡顿,建议先从react层面去考虑how 进行优化,then再去考虑how 优化数据管理层。关于上面提到的三个数据流管理工具,有利有弊,in the light of弊端,网上也有一大批优秀的解决programme和改进,感兴趣的读者可自行查阅。

relevant推荐:

以上就是reactYes? 处理数据流康南晗改谌荩琺ore请关注亚博足彩app其它relevant文章!

赞(0) 打赏
未经市聿坏米兀亚博足彩app首page » React 答疑

comment 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发relevantadvertisement投放 更专业 更精准

联系We

觉梦恼掠杏镁痛蛏鸵幌挛恼耡uthor

支付宝扫一扫打赏

微信扫一扫打赏

1/1