安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

理解了状态管理,就理解了前端开发的核心

9月1日 喵小咪投稿
  状态管理是前端整天遇到的概念,但是大家是否思考过什么是状态,管理的又是什么呢?
  我们知道,程序是处理数据的,数据是信息的载体,比如颜色是红色或蓝色这就是数据。
  那为什么不叫数据管理呢?状态和数据是什么关系?
  什么是状态
  状态是数据的变化,比如颜色是红色或蓝色是数据,而颜色从红色变为蓝色这就是状态了。
  状态的改变对应着视图的渲染或者某段逻辑的执行。比如颜色从红色变为蓝色可能就要重新渲染视图,并且执行发送请求到服务端的逻辑。
  通过视图交互或者其他方式触发状态的变化,状态变化联动视图的渲染和逻辑的执行,这就是前端应用的核心。
  为什么之前jQuery时代没咋听说状态管理的概念,而Vue、React时代经常听到呢?
  jQuery时代是手动把数据渲染到视图和执行数据变化之后的逻辑的,它可能没有明确的状态这一层,而是直接把数据渲染成dom,下次需要数据也是从dom来取的。
  而Vue、React前端框架的时代不需要手动操作dom和执行数据变化之后的逻辑,只要管理好状态,由前端框架负责状态变化之后的处理。
  状态管理管理的是什么呢?
  什么是状态管理
  状态管理具体有两层含义:
  状态变化之前的逻辑,一般是异步的。
  状态变化之后的联动处理,比如渲染视图或执行某段逻辑。
  比如React的setState不会马上修改状态,而是异步的批量的执行,把状态做一下合并。
  比如Redux的action在修改全局state之前也是要经历中间件的处理的。
  这些都是状态变化之前的异步过程的管理,是状态管理的第一层含义。
  再比如ReactsetState修改了状态之后要触发视图的渲染和生命周期函数的执行,hooks在依赖数组的状态变化之后也会重新执行。(vue的data修改之后会重新渲染视图、执行computed和watch逻辑)
  Redux修改了全局状态之后要通知组件做渲染或者做其他逻辑的处理,Vuex、Mobx等都是。
  这些是状态变化之后的联动处理的管理,是状态管理的第二层含义。
  我们知道了什么是状态,什么是状态管理,那前端框架Vue、React和全局状态管理的库Redux、Mobx、Vuex都是怎么实现状态管理的呢?
  状态管理的两种实现思路
  状态不会是一个,多个状态的集合会用对象的key、value来表示,比如React的state对象,Vue的data对象(虽然叫data也是指的状态)。
  怎么监听一个对象的变化呢?
  我们是不是可以提供一个api来修改,在这个api内做state变化之前的处理,并且在state变化之后做联动处理。
  这样的方案只能通过api触发状态修改,直接修改state是触发不了状态管理逻辑的。
  React的setState就是这种思路,通过setState修改状态会做状态变化之前的批量异步的状态合并,会触发状态变化之后视图渲染和hooks、生命周期的重新执行。但是直接修改state是没用的。
  那怎么让直接修改状态也能监听到变化呢?
  可以对状态对象做一层代理,代理它的get、set,当执行状态的get的时候把依赖该状态的逻辑收集起来,当set修改状态的时候通知所有依赖它的逻辑(视图渲染、逻辑执行)做更新。
  Vue的data监听变化就是用的这种思路,在状态get的时候把依赖封装成Watcher,当set的时候通知所有Watcher做更新。
  这种思路叫做响应式(reactive),也就是状态变化之后自动响应变化做联动处理的意思。
  代理get、set可以用Object。defineProperty的api,但是它不能监听动态增删的对象属性,所以Vue3改为了用Proxy的api实现。
  监听对象的变化就这两种方式:
  提供api来修改,内部做联动处理。
  对对象做一层代理,set的时候做联动处理,通知get时收集的所有依赖。
  前端框架状态变化的性能优化
  但是频繁的修改state不是每次都要做联动处理,有一些可以合并的,比如两次都把颜色改为红色,那后续逻辑就没必要执行两次,需要再做些性能方面的优化。
  所以React的setState是异步的,会做批量的state合并(注意,React的setState传入的不是最终的state,而是state的diff,React内部去把这些diffstate更新到state)。
  图片
  而Vue因为是直接修改的同一个对象,所以没必要做啥合并,它的Watcher执行是异步的,对多次放到队列里的Watcher做下去重就行了。
  图片
  组件间的状态管理
  组件内的状态管理就是这样的,利用前端框架自带的state机制来管理。
  那组件之间呢?一个组件的state变了如何联动其他组件变化?
  props
  通过props,把当前组件的state作为props传入其他组件就行了,这样就能联动变化。
  但是props只能一层层传递,如果组件和想联动变化的组件相隔很多层,传递props就很麻烦。
  这种情况下前端框架也都提供了解决方案,React提供了Context、Vue提供了EventBus。
  Context、EventBus
  React组件可以在context中存放state,当context中的state变化的时候会直接触发关联组件的渲染。
  Vue可以在一个组件内emit一个事件,然后另一个组件on这个事件,然后更新自己的data来触发渲染。不过这两个api在Vue3都废弃了。
  这种前端框架自带的任意层组件的状态联动方案只能处理简单的场景,复杂的场景还是得用全局状态管理库,比如Redux、Vuex、Mobx这些。
  为什么这么说呢?
  还记得状态管理的两层含义么?状态变化前的异步过程的管理,状态变化后的联动处理。
  Context和EventBus都只做到了状态变化后的联动处理,但是没有对状态变化前的异步过程管理做支持。
  比如多个组件都要修改context中的值(或者通过eventbus修改全局状态),这个过程都要执行一段异步逻辑,要做loading的展示,那多个组件里怎么复用这段loading的逻辑呢?
  还有,如果异步过程比较麻烦,需要用rxjs这样的库,用context和eventbus的方案怎么和rxjs结合呢?
  当然,是可以对context和eventbus做一些逻辑复用的封装和一些结合rxjs方案之类的封装的,但是比较麻烦。
  而且更重要的是如果你想做这些的时候,那也就没必要用context和eventbus了,直接用全局状态管理库就行。
  Redux、Mobx、Vuex
  redux就提供了中间件的机制,组件里发送action到store(存放全局state的地方),之前会经历层层中间件的处理,在这里就可以做一些可复用的逻辑的封装,比如loading的处理,也可以结合rxjs这种异步过程处理方案。
  redux里最常用的中间件就是reduxsaga和reduxobservable了,这俩都是做异步过程的管理的。
  reduxsaga是基于generator实现的,不管是同步还是异步,都只要声明式的描述要执行的逻辑就行,由saga内部的执行器会去做同步或异步的处理,描述异步逻辑就很简洁,而且reduxsaga提供了很多内置的逻辑封装。
  图片
  reduxobservable则是结合rxjs的方案了,把action变成数据源,经历层层opreator的处理,最后传递到store。可以用rxjs生态大量的oprator,做下组装就行,根本不用自己写异步逻辑的具体实现。
  图片
  mobx没有提供中间件机制,它的action是执行状态class的某个方法,可以用class的那套来做封装。
  有的同学对这些状态管理库不太熟,简单来介绍下。
  我们理清了状态管理的实现只有两种方案,一种是提供api做修改,一种是对state对象做响应式代理。
  前端框架的状态管理是这样,独立的全局状态管理库也同样是这样。
  redux就是提供api来修改的方案,通过reducer函数来对传入的action做处理,返回新的state。
  图片
  而且redux这种思路是函数式的思想,每个reducer都是输入和输出一一对应的纯函数,返回的state都是全新的,为了方便创建新的state,一般会搭配immutable库,只要修改属性就会返回新的state对象。
  mobx是响应式代理的方案,它对全局state做了一层代理(通过Object。defineProperty),状态的get收集依赖,set的时候触发依赖更新。
  图片
  所以这种方案很自然的可以把全局state组织成一个个class,是面向对象的思想,可以通过继承等方式实现逻辑复用。
  importReact,{Component}
  importReactDOM
  import{observer}
  observer
  classTodoListViewextendsComponent{
  render(){
  return
  {this。props。todoList。todos。map(todo
  )}
  ul
  Tasksleft:{this。props。todoList。unfinishedTodoCount}
  }
  }
  constTodoViewobserver(({todo})
  input
  typecheckbox
  checked{todo。finished}
  onClick{()todo。finished!todo。finished}
  {todo。title}
  li
  )
  conststorenewTodoList();
  ReactDOM。render(,document。getElementById(mount));
  vuex则像是两种思路的结合,内部是用响应式代理来实现的变化监听,但是暴露出的api却是redux的action那一套。
  图片
  和React搭配使用的话,需要把组件添加到状态的依赖中,这个不用自己调用subscribe之类的api,直接用一些封装好的高阶组件(接受组件作为参数返回新的组件的组件)就行,比如reactredux的connect,mobxreact的observer。
  总结
  讲了这么多,回过头来看一下就会发现:
  不管是前端框架内置的组件内状态变化管理的方案(react的setState、vue的直接修改data),还是前端框架提供的组件间的状态管理方案(props、react的context、vue的eventbus),或是第三方的全局状态管理方案(redux、vuex、mobx等),都没有脱离那两种实现状态管理的方式:提供修改状态的api或者对状态对象做一层响应式代理。也没有脱离状态管理的两层含义:对状态变化前的异步过程做管理,状态变化后做联动处理。只不过它们用在了不同的地方(前端框架内、全局状态管理库),提供了不同的封装形式(对象、函数),基于不同的思想(函数式、面向对象)结合了不同的异步管理方案(rxjs、generator自定义执行器)。
  所以,状态就是数据的变化。前端应用的核心问题就是管理状态,管理状态变化之前的通过视图或者其他方式触发的异步过程,管理状态变化之后的联动渲染和联动的逻辑执行。
  虽然我们会用不同的前端框架,不同的全局状态管理库,结合不同的异步过程处理方案,但是思想都是一样的。
  毫不夸张地说,理解了状态管理,就理解了前端开发的核心
投诉 评论 转载

三星GalaxyZFold3打造最强生产力支持120Hz刷新随着智能手机领域的不断发展和迭代,折叠屏手机进入了人们的视野。在强调效率的今天,折叠屏的优势在于更大的屏幕和更强的交互方式,为用户带来了更为高效的生产力,成为了商务人士移动办公……数字经济时代,数字化人才培养路在何方?数字经济作为发展迅速、创新活跃、辐射广泛的经济活动,正在成为全球经济复苏和增长的重要驱动力。十四五规划和2035年远景目标纲要均提出加快数字化发展建设数字中国,要求充分发挥海量……中国AI技术或超美国,将成全球AI大国当你把玩智能手机的时候,是不是被手机上的人脸解锁、拍照、美颜等功能深深吸引。当你走进商场,看到机器人跳着连你都不会的舞蹈,是不是也会驻足观看?而这些都是我们在生活中的AI技术。……俄罗斯双拳出击,给谷歌开出天价罚单,将美国一纸状书告上联合国正所谓多行不义必自毙,美国坏事做多了终究是会遭到报应的。这不,美国科技巨头谷歌就首先给其国内众多企业打了个样,告诉其他美企什么叫做自己作死。据环球网报道,由于谷歌多次未按要求删……理解了状态管理,就理解了前端开发的核心状态管理是前端整天遇到的概念,但是大家是否思考过什么是状态,管理的又是什么呢?我们知道,程序是处理数据的,数据是信息的载体,比如颜色是红色或蓝色这就是数据。那为什么……首都在线董秘预计云计算十四五末市场规模将突破1万亿,2020首都在线(300846)04月01日在投资者关系平台上答复了投资者关心的问题。投资者:董秘您好,目前国内云计算是否产能过剩?谢谢。首都在线董秘:您好,东数西算工程已……快递未上门老人取件途中猝死,快递公司难言符合流程这起纠纷的焦点,其实是合同条款是否如实履行的问题。这是一起因快递未上门而引发的纠纷。日前,重庆一名79岁老人在取完快递搬运上楼途中猝死的消息,引发关注。快递面单显示,配送……外媒疑惑中美之间的竞争是否促进了中国的科技进步?看网友回答自从川普同学带着美丽国和种花家开启了几年的经贸竞争,但几年了,种花家似乎没有受到太多的影响,反而越发有力,于是,就在美版知乎上,有人就很疑惑:中美贸易竞争间接促进了中国科技的发……2022年下半年全球电动汽车将每月增加近100万辆1。小鹏汽车回应车主开启辅助驾驶遇车祸近日,湖南岳阳,小鹏汽车车主邓先生称在国道上开启自动辅助驾驶行驶十几公里后,突遇一辆侧翻在道路上的汽车,没有任何报警和减速,车子径直……网友高价买iPhone12ProMax遇翻新机,换过外壳屏幕虽然iPhone13开启预售,但很多人对iPhone12系列的热情依旧不减。网友在某鱼买了一台美版二手iPhone12ProMax,成色不错,价格便宜,但拿到手才发现,这台iP……连年陷入亏损泥潭,快狗打车仍冲刺港股IPO文羊城晚报全媒体记者林曦实习生徐政媛近日,港交所信息显示,快狗打车通过港交所上市聆讯,准备冲刺同城货运第一股。快狗打车的前身为58同城旗下的速运业务,后来经过一系列的资本……三星这次良心了,从4999降到2799,IP683200万自声明:原创不易,禁止搬运,违者必究!在全球手机销量排行榜中,三星位于前三的名次中。三星手机在全球销量中,市场占比确实挺高的,但是在国内手机市场,三星手机的热度并不高。其原……
你还充吗?腾讯视频连续包月涨至25元各平台会费频上涨人工智能助力数学研究戴眼镜也可以用的VR,真的不晕!爱奇艺奇遇DreamVR一体指纹解锁最优解RTX3070只要6600元可以下山了RedmiK50电竞版与iQOO9该怎么选?网友仅凭4点,K智能化时代来临庞勃特科技开拓机器人乒乓球新蓝海I新赛道未来6G基站将像手机那么大,全球数量最多可达1000亿个八张图看懂华为的爆炸式增长谣言四起,小交易所集体关闭,三大所继续保留运营,并无佐证浅谈做互联网平台应该通过什么路径积累会员实现财务自由?从6799跌至5308,苹果5nm芯片iOS14,网友不等i榨汁机怎么用(小型便携式榨汁机怎么用)张飞坐骑是什么马?比赤兔更加霸气生活保健教你喝酒不伤身的方法沉与浮幼儿园大班科学教案5篇家用无线路由器牌子(家用无线路由器哪个牌子好)杂和野与好玩与有趣与有情怀一次有态度的倾听美丽的校园试玉要烧三日满,辨材须待七年期。意思翻译、赏析电烤箱烤饼干(掌握1步超简单)为什么欧美巨星很少来中国?都市空间视野中的知识分子研究今天是世界微笑日,你微笑了吗?

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利