前端状态管理设计——优雅与妥协的艺术

广告位招租
扫码页面底部二维码联系

如果我仍然去解释什么是状态管理器,为什么【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】我们需要它,这篇文章将会索然无味。我提出【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】的观点是,我们原本不需要状态管理器,但我【原创内容,转载请注明出处】原创内容,盗版必究。们确实需要状态管理。

原创内容,盗版必究。未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net【作者:唐霜】【作者:唐霜】

前端状态管理本文作者:唐霜,转载请注明出处。

【原创不易,请尊重版权】未经授权,禁止复制转载。【原创不易,请尊重版权】

非要去深究“状态”这个词,从后端服务的角原创内容,盗版必究。【转载请注明来源】度去解释更加能让我们理解。总而言之,我自转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。以为是地总结,“状态”的意思就是:现在的【转载请注明来源】【关注微信公众号:wwwtangshuangnet】样子。一个服务现在的样子主要是由运行时所本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】产生的内存和运算决定的,而且,它有终极的【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。时间观念,理论上任何时刻的状态都不同,因未经授权,禁止复制转载。【未经授权禁止转载】为它内部必然会有尽管细微的变化。

转载请注明出处:www.tangshuang.net【版权所有,侵权必究】【作者:唐霜】

前端状态管理这个概念出现之前,就已经有状【本文受版权保护】【转载请注明来源】态管理的实践了。我在2010年开始使用j【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.netquery,这是一个非常了不起的库,它将本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。复杂的DOM操作,通过简化和封装,成为实本文作者:唐霜,转载请注明出处。【未经授权禁止转载】质上的行业标准。HTML5标准发布后,采本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。用了querySelector这个接口,【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net可以说它完全是基于开发者对jquery的【作者:唐霜】【版权所有】唐霜 www.tangshuang.net认可度的考虑。那这和状态管理有什么关系呢【作者:唐霜】未经授权,禁止复制转载。?我想说的是,在jquery的年代,虽然转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net“前端状态管理”这个概念还没有产生,但是本文版权归作者所有,未经授权不得转载。【作者:唐霜】状态管理确真实存在。我们用一段基于jqu转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.netery的伪代码来看看。

本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net
var $div = $('#id')

$div.on('click', function() {
  if ($(this).data('show')) {
    return
  }
  $modal.show()
  $(this).data('show', true)
})

$modal.on('click', '.close', function() {
  $(this).hide()
  $div.data('show', false)
})

我们在实践中,使用dataset的特性,【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。直接在被操作的DOM节点上对一个模态框的【转载请注明来源】【本文首发于唐霜的博客】隐现状态【版权所有】唐霜 www.tangshuang.net进行管理。而在其他地方,我们可能会读出这原创内容,盗版必究。原创内容,盗版必究。个状态值,用来判断是否要执行某些操作。

本文作者:唐霜,转载请注明出处。【转载请注明来源】【作者:唐霜】本文作者:唐霜,转载请注明出处。

你看到的这种操作,在我们将“前端状态管理【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】”的概念抽象化之前,几乎随处可见。当然,本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。这是一种原始的状态管理,它只能处理单一的【原创内容,转载请注明出处】【原创内容,转载请注明出处】、分散的、临时的状态,无法对复杂的、耦合著作权归作者所有,禁止商业用途转载。【本文受版权保护】(依赖)的、持久的状态进行深度处理,或者【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net说处理起来很麻烦。其中的典型案例就是我多【原创不易,请尊重版权】【本文受版权保护】次提及的表单业务,在一个表单业务中使用j本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】query进行开发,所有的表单数据,必须转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net分散的、随意的,提交的时候,必须从很多个【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】地方把这些数据找出来,甚至还比较难找。

本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】【作者:唐霜】本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】

我们不禁要问:状态管理的本质是什么?【本文首发于唐霜的博客】

【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net【转载请注明来源】【转载请注明来源】

某一状态能够被有效记录。【未经授权禁止转载】

【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】转载请注明出处:www.tangshuang.net

我大学本科和硕士所属专业的大类是管理学,未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net不同专业对管理的解释不同,而对我而言,记著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。录则是一种有效管理。就像jquery时代【作者:唐霜】转载请注明出处:www.tangshuang.net,我们找到一种虽然原始,但行得通的方式管【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】理状态。

著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。

但是,我们往往发现,我们正在实践的东西,【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。有些是非常优秀的,但是,必须等到很多年(本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。3-5年)之后,被其他团队的某个项目带热【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。之后,才证明我们正在实践的东西是对的,是未经授权,禁止复制转载。原创内容,盗版必究。走在趋势上的,然而我们没有坚持到最后,因著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】为最后我们采用了市面上最热门的框架或库。【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net超前的东西往往一开始有很多人同时实践,但【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】是随着时间流逝,这些实践的人中,很多退出著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。了,在沉寂的发展中,会有一些坚持下来的团【关注微信公众号:wwwtangshuangnet】【作者:唐霜】队,最终成为主流,比如angularjs本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】团队。但不要着急,在angularjs还原创内容,盗版必究。未经授权,禁止复制转载。默默无闻时,甚至已经初露端倪时,仍然还是【转载请注明来源】【未经授权禁止转载】jquery的天下,直接对DOM节点操作【本文受版权保护】未经授权,禁止复制转载。的前端编程范式持续了至少6年左右,直到r【作者:唐霜】转载请注明出处:www.tangshuang.neteact提出virtual dom这样先【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。进的理念之后,jquery才逐渐淡出历史著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】舞台。angularjs团队至始至终都没【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net有超出jquery的统治高度。

【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】【本文首发于唐霜的博客】未经授权,禁止复制转载。

没有超出jquery统治高度的,还有ba【本文首发于唐霜的博客】未经授权,禁止复制转载。ckbone。我也多次提到过这个库,它至【本文受版权保护】【作者:唐霜】今还活着,你可以通过这里著作权归作者所有,禁止商业用途转载。查看它的文档。backbone的成就核心著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】在于它的Model本文作者:唐霜,转载请注明出处。(backbone是一个真正意义上的前端【原创不易,请尊重版权】【转载请注明来源】框架,但是它不处理view部分,它提供了【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。view的编程范式,但你需要使用jque未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】ry来完成所有view的更新)。我们来看【作者:唐霜】【关注微信公众号:wwwtangshuangnet】一个例子吧。

转载请注明出处:www.tangshuang.net原创内容,盗版必究。【原创不易,请尊重版权】【原创不易,请尊重版权】【未经授权禁止转载】
var Boy = Backbone.Model.extend({
  default: {
    name: 'tomy',
    age: 10
  },
})

var boy = new Boy()

boy.on('change:age', function(model, age) {
  // 现在我可以用新的age重新渲染(修改DOM)
})

boy.set('age', boy.get('age') + 1)

backbone中可没有我们现在熟知各种原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。花里胡哨的操作方式,对于模型实例中的状态本文版权归作者所有,未经授权不得转载。【作者:唐霜】,只能通过get进行获取,通过set进行原创内容,盗版必究。转载请注明出处:www.tangshuang.net修改,set也支持传入对象批量修改。而它【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】最大的亮点,在于模型上的on方法,这个方【本文首发于唐霜的博客】【本文首发于唐霜的博客】法实现了状态管理的一个质变。

【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。【原创内容,转载请注明出处】原创内容,盗版必究。

状态的变化能被有效感知和响应。本文作者:唐霜,转载请注明出处。

本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】

on/off这对监听方法来源于jquer原创内容,盗版必究。【作者:唐霜】y,但超越了jquery。jquery中【本文受版权保护】本文作者:唐霜,转载请注明出处。只针对DOM的事件系统,而backbon【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。e可以脱离DOM对数据变化进行监听。当数【本文首发于唐霜的博客】【转载请注明来源】据的变化被监听之后,就可以在监听函数中对【本文受版权保护】本文版权归作者所有,未经授权不得转载。view进行修改,而对于事件的响应,只需著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。要调用set方法修改数据。这样就做到了数【转载请注明来源】本文版权归作者所有,未经授权不得转载。据和界面代码的分离解耦,是一大进步。但b本文版权归作者所有,未经授权不得转载。【转载请注明来源】ackbone也止步于此。

转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net

使用set/get显然是一种妥协,监听时【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。,也为了和普通事件区分,必须加一个change:前缀,这也是一种妥协。如果回到2018年【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】去重新设计backbone,get可以做【原创不易,请尊重版权】原创内容,盗版必究。依赖收集,监听可以被优化,即使仍然采用s本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.netet/get接口,而不采用defineP【本文首发于唐霜的博客】【原创内容,转载请注明出处】roperty这样的黑魔法,也可以再进一未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。步,然而,时代终将止步于该止步之处。

【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】

对于开发者而言,虽然可以通过对状态变化的著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】监听,来实现状态和界面代码分离,确始终认转载请注明出处:www.tangshuang.net【作者:唐霜】为通过set/get这样的方法接口进行数【转载请注明来源】【原创内容,转载请注明出处】据操作,有违编程的优雅。这这条路上,an【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】gularjs走的更远。同样是基于jqu【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。ery打下的江山,backbone也是框转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net架,angularjs也是框架,然而当我【作者:唐霜】著作权归作者所有,禁止商业用途转载。们如今回头去看,虽然angularjs也著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】没有爆红,却踏踏实实的,成为一代框架典范转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】,成为前端工程化之鼻祖,同时,也是前端状【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。态管理的一大遗憾。

【原创内容,转载请注明出处】【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】

如果你使用过angularjs,你会喜欢原创内容,盗版必究。【本文首发于唐霜的博客】上它,当然前提是在那个年代。它通过一套被【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。称为脏检查机制的响应系统,让开发者可以通未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】过直接修改状态属性值,就映射到界面上。我转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。们来看下代码。

本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】
<div ng-click="updateName()">{{name}}</div>
function($scope) {
  $scope.name = 'tomy'
  $scope.updateName = function() {
    $scope.name = 'sam'
  }
}

$scope 是angularjs的内置服务,为了避【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net免一些作用域问题,推荐使用control著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。lerAs来管理。但我们且不去讨论这些问【转载请注明来源】本文作者:唐霜,转载请注明出处。题,我们看angularjs的代码,已然【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。见到来当代所熟悉的编程风格了。我们可以把未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】$scope当作是一个状态管理器,状态变转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net化,会通过angularjs的响应系统,【原创内容,转载请注明出处】原创内容,盗版必究。反馈到界面上去,view中所使用的数据素【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。材,和$scope上的属性名完全对应。

本文作者:唐霜,转载请注明出处。【转载请注明来源】未经授权,禁止复制转载。【版权所有,侵权必究】

状态的改变能驱动界面的变化。本文作者:唐霜,转载请注明出处。

本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net

angularjs的实现原理是,在ng-【本文受版权保护】【版权所有,侵权必究】click的触发之后,除了调用执行$scope.updateName之外,实际上还要执行内部的digest循未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。环过程,也就是脏检查的内部实现。只有经历【版权所有】唐霜 www.tangshuang.net【作者:唐霜】完这个digest之后,才能更新视图界面【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。。那么问题就由此而生,在有些情况下,这个本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。digest确实没有被触发,举个例子,在【未经授权禁止转载】【原创不易,请尊重版权】原生的ajax请求结束时修改$scope【本文受版权保护】【版权所有,侵权必究】.name就无法触发,于是angular【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】js提供了$apply方法解决这个问题。

著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】
$.get(url, function(data) {
  $scope.name = data.name
  $scope.$apply()
})

至此,一个angularjs的应用,它的【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。controller开始逐渐膨胀,慢慢的【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。随着业务逻辑的增长,一个function【作者:唐霜】【本文受版权保护】被撑到上千行代码。而在这上千行代码中,要本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。找到一个状态以及这个状态的变化过程,犹如【本文首发于唐霜的博客】未经授权,禁止复制转载。在大海中寻找绣花针般,无计可施。

转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【未经授权禁止转载】

问题出在哪里呢?直到今天,angular本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】已经迭代,旧版本几乎已经停止维护,这个问本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】题仍然没有被回答。我个人猜测,最本质的根【本文首发于唐霜的博客】【本文首发于唐霜的博客】源在于,angularjs没有按照严格的转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】MVC进行设计,它缺失了M层,所有的编程【本文受版权保护】著作权归作者所有,禁止商业用途转载。逻辑被写在controller函数中,任【本文首发于唐霜的博客】【未经授权禁止转载】由开发者自由发挥,修改视图状态。由于没有著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。对Model层进行强约束,导致代码里根本【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。分不清哪些是用于控制视图变化的交互逻辑,【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。哪些是用于控制数据变化的业务逻辑。而这个【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。问题,在后来的react、vue中其实也【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。存在。

【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。

一个更严重的问题,angularjs的d【本文受版权保护】【本文首发于唐霜的博客】irective(相当于组件)支持双向数【未经授权禁止转载】【原创内容,转载请注明出处】据绑定,导致外层状态在内层directi【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。ve中被修改,在调试问题时,由于无法掌握著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net状态变化的顺序,使开发者可以崩溃砸电脑。【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net并且随着W3C标准的推进,“组件”这个概【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net念开始慢慢成为开发的核心概念。而于此同时原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】,同样基于组件思想而生的react就像横本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。空出世一样,像一记银弹击碎了jquery未经授权,禁止复制转载。【版权所有,侵权必究】多年美梦,从此前端编程范式实现了转变。

【原创内容,转载请注明出处】【未经授权禁止转载】【原创内容,转载请注明出处】

react的编程范式核心来自virtua【原创不易,请尊重版权】【原创内容,转载请注明出处】l dom,虚拟DOM的思想直接使得前端原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】编程范式发生转变。通过将DOM树映射到一著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。个内存对象,通过对虚拟DOM的对比,只更著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】新实际DOM中的少量节点,从而避免频繁操著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】作DOM带来的性能损耗。但virtual本文版权归作者所有,未经授权不得转载。【转载请注明来源】 dom的杀手锏在于,将实际的DOM抽象著作权归作者所有,禁止商业用途转载。【转载请注明来源】为虚拟DOM之后,虚拟DOM是否再回到实【原创内容,转载请注明出处】【转载请注明来源】际DOM就是可选择的事情,因为基于这套理【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】论,虚拟DOM还可以为其他渲染方式提供驱【原创内容,转载请注明出处】【未经授权禁止转载】动力,比如react-native,或者【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。渲染canvas。而驱动virtual 【本文受版权保护】【作者:唐霜】dom发生变化的,竟然是状态。

未经授权,禁止复制转载。【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net原创内容,盗版必究。【转载请注明来源】

这是一个大转变。react一直提倡一种纯著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】UI组件,这种组件完全受控于其props【关注微信公众号:wwwtangshuangnet】【本文受版权保护】的值,像纯函数一样,props在解构全等原创内容,盗版必究。【原创内容,转载请注明出处】的情况下,其渲染出来的效果是一模一样。而【原创内容,转载请注明出处】【本文首发于唐霜的博客】支配props变化的,来自于顶层组件一层本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。一层的传递。最终,一个界面将要展示成什么【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。样子,取决于一个状态,由这个状态参与组成【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。虚拟DOM,并反映到真实DOM中去。状态本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。发生变化时,按照一层一层传递的单向数据流【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】方式,让所有的自组件按照最顶层组件的状态【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】进行渲染。

本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。

界面是状态的映射。【原创内容,转载请注明出处】

【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。

在这种思想熏陶下,大约2016年,整个前【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】端的编程范式都以此为基础,所涌现出来的v【转载请注明来源】原创内容,盗版必究。ue,也直接借鉴这套思想进行编程。一个状【转载请注明来源】原创内容,盗版必究。态,对应一个界面,这简直是天才的想法。基【未经授权禁止转载】【转载请注明来源】于这种思想,那么把所有的状态按照事件线录未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。制下来,就可以重放界面变化的所有,这种录【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】制,将原本庞大的界面数据,抽象为状态这一【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】小量数据,这种思维在游戏录制领域也被使用【作者:唐霜】【作者:唐霜】过。

【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】未经授权,禁止复制转载。【原创不易,请尊重版权】

诚然,虽然“映射”思想颠覆了传统前端编程未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】更新DOM的范式,但react的编程范式【本文首发于唐霜的博客】【转载请注明来源】所遵循的单向数据流确带来了巨大麻烦。这种【作者:唐霜】【原创不易,请尊重版权】一层一层传递的方式,虽然保证了“映射”行【关注微信公众号:wwwtangshuangnet】【转载请注明来源】为的纯正性,但无法适应实际生产过程中所带转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】来的写作和调试麻烦的问题。如果由于一个点未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】击操作需要通过10层组件的传递,才能对点著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net击做出响应,那么很可能就会出问题。单向数原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。据流听起来让数据流很清晰,但是对应到代码本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】中,发生一个事件发生后,这个事件信息,被著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。如何传递,成为极其复杂的逻辑,那么看似清【转载请注明来源】本文作者:唐霜,转载请注明出处。晰的流,就变成了汹涌的浊流。

【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。【转载请注明来源】

中心化的状态管理孕育而生,redux、m本文作者:唐霜,转载请注明出处。【本文受版权保护】obx这些都是佼佼者。这些,就是我们现在转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。真正意义上所称的状态管理器。它们当然是为【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。了管理状态。redux是一朵奇葩,它火,未经授权,禁止复制转载。【本文首发于唐霜的博客】火到爆炸,但是你去阅读它的源码,却又很简【原创内容,转载请注明出处】未经授权,禁止复制转载。单。大道至简,在这些年的编程体验中,我逐【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】渐体会到,简单,是一切的根本未经授权,禁止复制转载。。redux的使用非常简单,接口就那么几【本文首发于唐霜的博客】【原创不易,请尊重版权】个。然而,它确衍生出了自己的生态,它把自【作者:唐霜】【关注微信公众号:wwwtangshuangnet】己的概念体系发展成为蓬勃的森林。我的天!原创内容,盗版必究。【原创不易,请尊重版权】原本简单的东西,非要通过概念复杂化。设计,核心是简单,工具,用完即走就行。【本文受版权保护】同样的错误,在mobx身上重蹈覆辙。它的著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】设计理念也非常的具有颠覆性,引入观察者模未经授权,禁止复制转载。【未经授权禁止转载】式,将状态的变化通过观察者模式进行抽象,本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。并且通过完美的封装,使得更新状态的方式和【转载请注明来源】著作权归作者所有,禁止商业用途转载。普通修改一个对象没有两样。然而,过渡设计著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。让它和开发者注定无缘。话说回来,但是在状本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】态管理这个点上,它们的核心思想保持了一致【原创不易,请尊重版权】【作者:唐霜】,都是:

本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【作者:唐霜】【版权所有】唐霜 www.tangshuang.net

集中管理状态,共享状态。未经授权,禁止复制转载。

本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】

集中管理实际上是共享的前提,但也超越了共原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。享这一单项功能,集中管理状态,可以用一个【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net状态,概括一组组件,甚至一个应用的整体状转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】态,在映射思维驱动之下,连路由也要状态化【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】,也就是说,整个应用的一切行为都由中心化【作者:唐霜】【未经授权禁止转载】的状态管理器决定。框架层、UI层只是应用【本文首发于唐霜的博客】【本文首发于唐霜的博客】的壳,而状态以及状态的驱动才是应用的魂。【原创内容,转载请注明出处】【原创内容,转载请注明出处】状态管理器,通过连接器将状态的变化反馈到【转载请注明来源】【版权所有】唐霜 www.tangshuang.net具体的某个组件中,而这个组件,可以通过原【原创不易,请尊重版权】【本文受版权保护】本的单向数据流将状态传入更深的子组件中。原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.netUI层像提线木偶一样,被状态管理器完完全未经授权,禁止复制转载。【本文受版权保护】全的控制着。

本文作者:唐霜,转载请注明出处。【作者:唐霜】【作者:唐霜】【原创内容,转载请注明出处】

然而,物极必反。react官方提出来的f【版权所有,侵权必究】未经授权,禁止复制转载。lux,本身就打破了单向数据流的体系,它著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】使数据可以通过多条管道进行传递,而它的核【原创不易,请尊重版权】【原创内容,转载请注明出处】心,就是要建立一条便捷通道,跨过多层组件【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】,使分散在两个树枝上的节点组件直接通信。【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net虽然flux通过非常复杂的概念,试图解释【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。自己是遵循单向数据流,但是不可否认,它只【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net是在原来的单向流之外,又开了一条流,现在未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。有两条通道,但你只能选择其中之一,这样你本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。才能单向数据流,从而保证界面和状态之间的著作权归作者所有,禁止商业用途转载。【转载请注明来源】映射关系。flux是妥协的产物,它是为了【未经授权禁止转载】【作者:唐霜】解决react带来的问题而产生的,而很不【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】幸,为了解决这个问题,flux带来了更多原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】的问题,妥协,本质上是债务未经授权,禁止复制转载。【作者:唐霜】

【版权所有,侵权必究】转载请注明出处:www.tangshuang.net原创内容,盗版必究。【转载请注明来源】未经授权,禁止复制转载。

更致命的是,中心化的状态管理面临严重的问【未经授权禁止转载】转载请注明出处:www.tangshuang.net题。状态,本身是必要的。状态解决了临时保本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】持和最终决定两个环节的冲突,以HTML中【本文首发于唐霜的博客】【原创内容,转载请注明出处】的select标签(本质就是一个组件)为著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】例子,哪一个option被选中了呢?这得【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】看当前select的状态,但这并不代表当【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net前被选中的值将作为你最终提交的值,你提交原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】的值,往往是看不见的option的val未经授权,禁止复制转载。【未经授权禁止转载】ue属性值。同样的情况比比皆是,例如你需本文作者:唐霜,转载请注明出处。【作者:唐霜】要打开一个模态框,在里面输入东西,或者选本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net择选项,但是模态框会给你一个cancel转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。的能力,当你点击cancel的时候,之前【未经授权禁止转载】【原创不易,请尊重版权】的操作会被重置。而这些临时保持的状态,根【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net本没有必要进入中心化管理的状态管理器中,原创内容,盗版必究。【转载请注明来源】一旦进入中心化状态管理器,那么就遇到内存【原创不易,请尊重版权】【版权所有,侵权必究】持久不能释放,还要解决数据重置等问题。但【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。尴尬的场景又在于,如果不进中心化状态管理【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。器,那映射思想又无法完全实现,一个状态一【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net定对应一个界面的理想模式无法复现。这个问【本文首发于唐霜的博客】【作者:唐霜】题,只要是共享数据,都会碰到,不一定是共著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】享状态,共享一个函数,共享一个模块,共享【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。一个类的实例,都会遇到,所以,这是共享问【版权所有,侵权必究】【原创内容,转载请注明出处】题带来的普遍性问题。那么怎么去解决呢?

【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】

还有一个大问题,集中管理状态的代价是状态【版权所有,侵权必究】【本文受版权保护】的domain问题,一份完整的状态确实好【作者:唐霜】【本文首发于唐霜的博客】处多多,但是带来的问题是,原本和组件无关本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。的状态变化,也会因为状态整体的变化被通知原创内容,盗版必究。【作者:唐霜】重新执行virtual dom的diff【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】操作。不过这是有办法解决的,无论是通过状【作者:唐霜】【关注微信公众号:wwwtangshuangnet】态管理器自身的优化也好,还是通过组件的优【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。化也好,都可以做到根据需要的状态变化来决转载请注明出处:www.tangshuang.net【作者:唐霜】定自身是否要做这个diff。可是大状态始【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net终是个隐患,不仅面临内存问题,也面临数据未经授权,禁止复制转载。【未经授权禁止转载】重复、难相互依赖等问题。

本文作者:唐霜,转载请注明出处。【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。

直到react hooks出现,这个局面转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net又被打破。hooks虽然表面上是让fun【作者:唐霜】【作者:唐霜】ctional组件也可以在不同的生命周期【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。环节上执行某些任务,但是本质上是重新定义转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。组件在什么情况下重新diff。hooks原创内容,盗版必究。【本文首发于唐霜的博客】函数的重点不在第一个参数,而在第二个参数著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。(依赖)。当依赖发生变化时,需要执行对应原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net的变化。变化源自状态的变化。hooks依未经授权,禁止复制转载。未经授权,禁止复制转载。赖状态,但是实际上定义的是动作及其触发的【版权所有,侵权必究】原创内容,盗版必究。条件。

原创内容,盗版必究。【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。

状态不是状态,而是动作。【版权所有】唐霜 www.tangshuang.net

著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net【转载请注明来源】未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。

从更小粒度去解释,视图层的每一个变化,是【原创内容,转载请注明出处】原创内容,盗版必究。完成什么动作。这就是hooks带来的变化【原创内容,转载请注明出处】【作者:唐霜】。这个粒度小到什么程度呢?atom。Re本文作者:唐霜,转载请注明出处。【转载请注明来源】coil是facebook发布的一个状态【原创内容,转载请注明出处】【原创不易,请尊重版权】管理工具,基于hooks的技术,实现状态本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net共享。和集中管理状态不同,recoil是本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】小到原子级别的状态管理。通过atom定义【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。一个原子状态,通过selector定义一本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。个依赖原子状态的复合状态(相当于计算属性【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net),在依托hooks,实现状态共享。由a【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】tom定义的原子状态,它的状态到底是什么【版权所有,侵权必究】转载请注明出处:www.tangshuang.net并不重要,我们不需要取出来看看,我们要做本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。的,是在hooks加持下,把握住状态变化未经授权,禁止复制转载。【本文受版权保护】的所带来的影响,也就是每一个动作。

【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。

听上去就像在胡扯,事情会变得越来越复杂。【作者:唐霜】【原创内容,转载请注明出处】设计,核心是简单。这里的简单,不单单是使【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】用起来很简单,而且理解起来也要很简单。对【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。于一个工具而言,我们要止于至简【关注微信公众号:wwwtangshuangnet】。我们追求简单,但防止过犹不及。在设计工原创内容,盗版必究。【版权所有,侵权必究】具时,有的时候,我们可以设计出超强超灵活【原创内容,转载请注明出处】【原创内容,转载请注明出处】的能力,但是,超出简单部分的功能,往往使本文作者:唐霜,转载请注明出处。【本文受版权保护】得使用成本和理解成本极速上升。状态管理器本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】的本质,是管理状态,是共享状态。过度设计未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】,过度技术化,都是过犹不及。当recoi原创内容,盗版必究。【原创不易,请尊重版权】l发布的时候,大家开始讨论actor m【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】odel,这是过犹不及。我们做开发设计,本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】并遵循某个模型进行设计,而是遵循使用者的【未经授权禁止转载】【本文首发于唐霜的博客】使用习惯进行设计。当然,我不是说要迁就使【本文受版权保护】转载请注明出处:www.tangshuang.net用者,而是说让使用者付出最低的成本得到最【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】高的回报,简单原则是达到这一目标的终极武【原创内容,转载请注明出处】【原创内容,转载请注明出处】器。为了简单,我们有的时候不得不放弃一些【本文受版权保护】【版权所有】唐霜 www.tangshuang.net原本可以让工具更强大的能力,但是不要着急【本文受版权保护】【版权所有】唐霜 www.tangshuang.net,这给我们开发工具提出了另外一个要求,就【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】是扩展性。简单是对使用者说的,而扩展性则著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】是对开发者说的。通过扩展性,简单工具可以转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】变成功能强大的功能,扩展性设计是考验能力【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。的,并非每个开发者都能做到,但是,这是基未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。本面。

本文作者:唐霜,转载请注明出处。【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。

挑选优质特性本文作者:唐霜,转载请注明出处。

著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。

应用没有有意识地状态管理并非不行,以最早【作者:唐霜】【版权所有,侵权必究】的jquery.data方式管理一个状态本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】也未尝不可。但如果需要有意识的进行状态管【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net理,那么,我们不得不需要一个状态管理器。【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。虽然我们可以挑选市面上已有的状态管理器,著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。但我们并不需要。我认为redux之所以经原创内容,盗版必究。未经授权,禁止复制转载。久不衰,核心的核心就在于简单。然而,并不本文作者:唐霜,转载请注明出处。原创内容,盗版必究。是简单我们就一定要用它,如果它的简单正好【本文首发于唐霜的博客】原创内容,盗版必究。复合我们的实践场景,那么它是不二之选,但未经授权,禁止复制转载。【作者:唐霜】是它的简单在应对我们的场景的时候略有不足【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。,由于木桶原理,它将永远无法满足我们的要未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。求。所以,手撸状态管理器在所难免。

本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net【转载请注明来源】【作者:唐霜】【版权所有】唐霜 www.tangshuang.net

当然,我们手撸,并不代表我们要全撸,例如【原创不易,请尊重版权】【本文受版权保护】,我们可以基于已有的redux,利用它的著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。扩展性,撸出自己的状态管理器。然而核心要【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】点还是在于,如何提供低成本的使用者开发体转载请注明出处:www.tangshuang.net【本文受版权保护】验。我们基于redux撸出来的,我们可以著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】另外取一个名字,将我们的用法和接口暴露给【本文首发于唐霜的博客】【未经授权禁止转载】使用者,我们全然不提redux,使用者但本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。凡用的舒服,没有吐槽,就代表这是成功的,原创内容,盗版必究。未经授权,禁止复制转载。此时我们再提redux,会让我们的成果充原创内容,盗版必究。未经授权,禁止复制转载。满乐趣。而如果一开始就大书特书我们是基于【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。redux的,想加持光环,那么得到的结果原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】必然是,如若不是真的好用到爆炸,断然收不【未经授权禁止转载】【作者:唐霜】到好评。

著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】

既然要开始撸状态管理器,我们就要设计这个著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。状态管理器的核心特质,缺少这些特质会是我【转载请注明来源】【原创不易,请尊重版权】们自己都无法忍受的。

本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】【转载请注明来源】
  • 简洁的状态定义,拒绝reducer【未经授权禁止转载】
  • 【版权所有,侵权必究】未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net
  • 状态domain,拒绝庞大状态树的细小变【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。动都惊动整个virtual dom重新计未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net
  • 原创内容,盗版必究。原创内容,盗版必究。【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】
  • 回溯能力,可撤销变化【版权所有】唐霜 www.tangshuang.net
  • 本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】【本文首发于唐霜的博客】【原创内容,转载请注明出处】
  • 重放能力,整个应用可以根据时间线完整播放
  • 【未经授权禁止转载】【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】
  • 局部状态可销毁,以释放内存【关注微信公众号:wwwtangshuangnet】
  • 【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。
  • 局部的共享,基于某一系列流程的临时状态,著作权归作者所有,禁止商业用途转载。【转载请注明来源】当这一系列流程结束时,共享状态可销毁
  • 【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】
  • 同时支持hooks和class comp【本文首发于唐霜的博客】原创内容,盗版必究。onents
  • 【本文受版权保护】本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net
  • 简洁的状态更新方式,深层节点更新不需要写【原创不易,请尊重版权】【原创内容,转载请注明出处】非常复杂的解构
  • 著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。
  • 优雅的异步支持本文作者:唐霜,转载请注明出处。
  • 【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net

其中,简洁的状态更新方式有一个库可以推荐原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】:immer。这个库只有一个接口,它的使【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。用方式如下:

【本文受版权保护】著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】
import produce from "immer"
const next = produce(current, draf => draf.some.name = 'dona')
setState(next)

大道至简!大道至简!大道至简!immer未经授权,禁止复制转载。【未经授权禁止转载】的作者简直就是天才。使用immer遵循了著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】immutable的社区范式,同时又可以【作者:唐霜】转载请注明出处:www.tangshuang.net采用mutable的操作方式,虽然在实战【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】中确实还有些坑,然而,对比原本写一大堆解【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net构符号的做法,这个接口简直是上帝的馈赠。

【本文首发于唐霜的博客】【本文受版权保护】【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】

还有一个点需要单独指出,重放功能实际上并【原创内容,转载请注明出处】未经授权,禁止复制转载。不是强制的,因为对于大多数应用而言,要实【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】现完全的重放,其实是不大可能的,最严重的转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。原因有两点:1)我们无法穿透所有组件,在本文作者:唐霜,转载请注明出处。【本文受版权保护】大部分组件中,我们不可避免的会用到内部状著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。态,而这些内部状态的变化我们无法收集到,本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net因此,也就无法重放由于组件的内部状态变化原创内容,盗版必究。原创内容,盗版必究。带来的界面变化,一旦无法重放界面变化,就著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】会出现问题,因为DOM的变化具有副作用,【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】下一个DOM树的基础是上一个DOM树,如【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net果某些变化没有发生,后续变化所依赖的DO【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。M节点可能根本就不存在,应用会报错;2)本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net在状态中,我们不可避免的使用某些实例对象本文作者:唐霜,转载请注明出处。【转载请注明来源】,基于class的实例对象有内存依赖,我【原创内容,转载请注明出处】【转载请注明来源】们无法将它们保存到服务器端,在从服务器端【作者:唐霜】【版权所有,侵权必究】拉出来进行回放。由于这两个原因,实际上要【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】完全回放一个应用,是很难的。

著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】【原创内容,转载请注明出处】【未经授权禁止转载】

有没有其他方向?转载请注明出处:www.tangshuang.net

【转载请注明来源】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。

有的。我们谈状态管理,本质上无法摆脱应用【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。层面的架构思维,而且这里仅仅是指围绕数据【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】流的前端应用(Management Sy本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】stem),我们几乎很少在游戏这种视觉系本文作者:唐霜,转载请注明出处。【作者:唐霜】统中大谈前端状态管理。既然是Manage【转载请注明来源】原创内容,盗版必究。ment System,那么我不禁要问,【本文受版权保护】转载请注明出处:www.tangshuang.net状态管理的目的,是技术的,还是应用的?很【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net显然,状态管理的目的,是为了让应用系统良【本文首发于唐霜的博客】【未经授权禁止转载】好运作,保障系统工作稳定准确。而我们要面未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。对的实际情况是什么呢?并非如何在组件之间【作者:唐霜】【转载请注明来源】共享状态。我们的实际情况是,我们需要在不【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】同子模块之间协调,甚至,我们需要在不同的原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。客户端之间协调。这里面的核心点实际上是“转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。业务逻辑”。如果我们同时拥有手机端和PC【本文受版权保护】未经授权,禁止复制转载。端应用,虽然它们在视图层面完全不同,然而原创内容,盗版必究。本文作者:唐霜,转载请注明出处。在business层面,却是一定一致的,【原创内容,转载请注明出处】原创内容,盗版必究。否则系统就不可靠了。如何保障业务层面的一【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。致性呢?

【原创内容,转载请注明出处】【本文首发于唐霜的博客】原创内容,盗版必究。原创内容,盗版必究。【本文首发于唐霜的博客】

对于服务端应用而言,特别是今天这个时代,【未经授权禁止转载】【原创内容,转载请注明出处】分布式系统已经是基础范式了,多个节点如何【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】保障同一个用户的业务操作是一致的,实际上转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net,它们还是要共享一个状态,这个状态可能存【原创内容,转载请注明出处】【原创内容,转载请注明出处】在redis中,可能通过Kafka进行同本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】步。业务逻辑的推进,依赖这些状态。看看后本文版权归作者所有,未经授权不得转载。【本文受版权保护】端是怎么处理的?是在模型中专注于整理出每【版权所有,侵权必究】【作者:唐霜】一个业务原子操作,并在接收到特定事件(或【转载请注明来源】本文版权归作者所有,未经授权不得转载。请求)时,按照业务顺序,组装完整的业务逻【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net辑出来。而现在前端是怎么做的?以reac【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】t为例,几乎全部的react应用,都是将【转载请注明来源】【转载请注明来源】业务逻辑写在组件中,因为业务操作必须依赖【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】用户的操作,而用户的操作必须在视图层中予【本文受版权保护】转载请注明出处:www.tangshuang.net以反馈。所以在react组件中写业务逻辑【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】非常正常,这回到了angularjs的老【原创不易,请尊重版权】【原创内容,转载请注明出处】路子上,特别是强调functional+著作权归作者所有,禁止商业用途转载。【作者:唐霜】hooks的写法之后,我很容易想象到未来【未经授权禁止转载】原创内容,盗版必究。的react组件和angularjs的c本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】ontroller函数差不多,写出上千行【转载请注明来源】著作权归作者所有,禁止商业用途转载。代码也不是不可能,到时候没人敢动这个组件【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net

【未经授权禁止转载】【转载请注明来源】【版权所有,侵权必究】【本文首发于唐霜的博客】

而这这一点上,我恰恰发现vue比reac【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。t好太多了。vue的结构是<tem【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】plate><script&【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】gt;<style>,这样的【原创不易,请尊重版权】【作者:唐霜】结构看上去符合早期的编程习惯,模板样式加【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】脚本嘛!然而,如果再去琢磨vue的scr本文版权归作者所有,未经授权不得转载。【作者:唐霜】ipt部分,我发现实际上vue所expo原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】rt出去的对象,本质上是一个类似模型的定【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】义(类似配置对象)。

转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【本文首发于唐霜的博客】
{
  data,
  computed,
  methods,
  watch,
}

一个模型,总是围绕自己目标所需要的数据进本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】行处理。如果写过php应用,大部分php【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。框架都会有模型层,而在编写模型时,强调的【原创内容,转载请注明出处】【原创内容,转载请注明出处】,都是只进行数据的读写和计算,而不处理任【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】何视图的东西,处理视图的东西,需要在控制【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】器中读取模型上的数据,自己进行组装。所以【原创不易,请尊重版权】未经授权,禁止复制转载。,模型,是对单一目标数据的总体概括,具有【作者:唐霜】【关注微信公众号:wwwtangshuangnet】业务逻辑的抽象性,无法单独完成整个业务流转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】程,但是却规定了业务逻辑的核心部分,等待【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。开发者使用这些部分,组装出完整的业务流程著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。

本文作者:唐霜,转载请注明出处。【作者:唐霜】【版权所有】唐霜 www.tangshuang.net【作者:唐霜】【版权所有】唐霜 www.tangshuang.net

不过,vue的组件定义不仅仅包含这些东西【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。,同时还有生命周期函数,子组件引用,pr【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。ops等等东西,而这些东西的整体,又是为未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。视图编程服务的,因此,最终它和模型也只是【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net插肩而过。状态管理的下一个方向,我恰恰认【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。为是去弥补这个领域。前端架构至始至终,都原创内容,盗版必究。【未经授权禁止转载】没有在模型层抽象出犹如后端一致的模型管理【原创内容,转载请注明出处】【本文受版权保护】,而发展至今,也应该是时候去往这个坑填一【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。填了。所以,我在写完react-tyshemo【原创内容,转载请注明出处】之后,有一种自豪感。我感觉自己好像触摸到转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】一点点这个问题的边缘了。这个库,可以做到【原创不易,请尊重版权】未经授权,禁止复制转载。定义状态就定义状态,在定义函数中,把状态本文作者:唐霜,转载请注明出处。【未经授权禁止转载】的所有演变都定义完整(也就是和上述vue【作者:唐霜】【本文受版权保护】组件script中的部分子集一致),然后本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】通过connect注入给组件使用,对于组【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】件而言,它就像只能从模型中读取属性和方法【作者:唐霜】【版权所有】唐霜 www.tangshuang.net一样,在遇到对应的交互事件之后,调用模型【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】上的方法去驱动模型中的状态变化,然后返回【原创不易,请尊重版权】【转载请注明来源】来又更新自己。这样就做到了数据模型的定义【作者:唐霜】本文作者:唐霜,转载请注明出处。和视图层(react组件)的分离,在手机【作者:唐霜】【未经授权禁止转载】端、PC端之间公用同一个模型成为可能。

【本文首发于唐霜的博客】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】

在react生态里面,炫技的不在少数。但【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。要解决问题,而且要简单地解决问题。将状态著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】管理升级到前端模型构建之后,模型逻辑和视【本文首发于唐霜的博客】【版权所有,侵权必究】图逻辑就可以完全分离。而由于我们大部分情【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】况下,会在模型中写业务逻辑,在视图中写交著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。互逻辑,所以只需要将它们组装起来。但是,【原创不易,请尊重版权】【版权所有,侵权必究】有趣的地方在于,可以拆分开来。而且,这也原创内容,盗版必究。转载请注明出处:www.tangshuang.net带来了另一个好处,由于业务逻辑的部分被独著作权归作者所有,禁止商业用途转载。【作者:唐霜】立出来,那么在不同端,就可以被复用,手机【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】端、PC端、其他端,可以基于同一个模型,原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】但视图却可以不同,视图因为只负责交互逻辑【未经授权禁止转载】【本文首发于唐霜的博客】,所以反而更抽象,变量命名都可以抛开业务【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net单词使用更抽象的词汇来命名。一旦业务逻辑原创内容,盗版必究。转载请注明出处:www.tangshuang.net的东西通过模型层面,和react视图编程【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】拆分开,那么,真的就可以做到,react【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】组件负责纯UI,而模型负责纯业务逻辑,中本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。间在通过某种控制器将两者粘连在一起,会是原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。另一翻编程的景象。

未经授权,禁止复制转载。【本文受版权保护】著作权归作者所有,禁止商业用途转载。

最后一句本文作者:唐霜,转载请注明出处。

【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】【原创不易,请尊重版权】

如果我们能够从历史的角度去观察,往往能够原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。发现,世界上没有完美的事物,有一种说法“【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】历史都是妥协出来的”,我们可以换一个好听本文版权归作者所有,未经授权不得转载。【转载请注明来源】的词,叫“博弈”,但是无论如何,我们都在本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net追求着,每个人的追求不同,代码风格的优雅【未经授权禁止转载】未经授权,禁止复制转载。,代码量少,代码性能极致,代码明显没有b未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。ug……这些追求,驱动着我们不断探索和思【版权所有】唐霜 www.tangshuang.net【作者:唐霜】考。

【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。

2020-05-20 7940 ,

为价值买单,打赏一杯咖啡

本文价值79.4RMB
已有5条评论
  1. noodles 2024-07-03 16:13

    学习了

  2. zhoulujun 2022-02-05 18:54

    大道至简,非常认同

  3. LooperChu 2021-10-10 16:34

    我觉得单纯从使用者的角度来说redux是“简洁”了自己“麻烦”了别人,mobx正好相反“麻烦”了自己“方便”了别人,也许是我们的业务还没复杂到一定程度,但单就我们自己的使用上来说转到mobx后体验比之前用redux要好一些,也许是之前用redux的方式不对,总觉得redux那一套写起来繁琐,虽然可以通过进一步的封装来降低繁琐程度,但还是没有mobx那种开箱即用的感觉。

    • 否子戈 2021-10-10 16:48

      非常赞同你的观点。redux更像是基于状态机的模型,而mobx更像是类的模型,更符合我们面向对象的编程习惯。

    • 2024-01-03 16:52

      mobx确实爽,直观,在flutter中也有类似的叫getx,两者真的很像,都是极其简单,符合直觉