1。什么是状态? jQuery时代,JS代码中混杂DOM结构,各个流程庞杂交织时,就形成面条式代码,当使用发布订阅模型时,调试会一团乱麻。 jQuery是针对过程的命令式编程,而那么多命令,最终都是为了更新UI中的数据,为什么不直接去改数据呢? 北京上海,把city北京变为city上海就行。不管飞机火车步行抛锚,也不管路上会不会遇到王宝强, 现代前端框架的意义,就是问题解决思路的革新,把对过程的各种命令,变为了对状态的描述。 什么是状态?状态就是UI中的动态数据。2。React中的状态 2013年5月React诞生。但2015年之前,大概都是jQuery的天下。2015年3月React0。13。0发布,带来了class组件写法。 在Reactclass组件时代,状态就是this。state,使用this。setState更新。 为避免一团乱麻,React引入了组件和单向数据流的理念。有了状态与组件,自然就有了状态在组件间的传递,一般称为通信。 父子通信较简单,而深层级、远距离组件的通信,则依赖于状态提升props层层传递。 于是,React引入了Context,一个用于解决组件跨级通信的官方方案。 但Context其实相当于状态提升,并没有额外的性能优化,且写起来比较啰嗦。 为优化性能,一般会添加多个Context,写起来就更啰嗦。在项目没那么复杂时,还不如层层传递简单。3。什么是状态管理? 实用主义来说,状态管理就是为了解决组件间的跨级通信。 当然,在使用状态管理库时,其会带来一些衍生的思维模式,比如如何组织state,如何拆分公共逻辑、业务逻辑、组件逻辑等,但归根结底,这些都不是核心缘由。 核心就是为了解决实际问题为了通信。其它的各种概念与哲学,都不是必要的。 Context没那么好用,React官方也没什么最佳实践,于是一个个社区库就诞生了。4。class时代的状态管理 Reactclass组件时代,就是Redux(及其相关衍生库)与MobX的故事。 Redux是符合React理念的实现。而MobX这种监听的模式,特点是不够React,但用起来简单。 Redux的利弊已讨论太多,简单来说,开发者关心的是使用,而Redux关心的是哲学。 之前开玩笑说,其实Redux用一行代码就可以表示,却写出了论文规格昏昏欲睡的文档:createStore(reducer,state)({dispatch:(action)(statereducer(state,action))}); 而几乎所有React状态管理器的原理,其实都很简单,一个观察者模式的实现: 在各个组件中订阅listener,state更新时,再把listener都调用一遍,从而触发组件更新。5。为什么是Hooks? Reactclass组件存在以下问题:this。state是一个对象,每次更新局部,更新时也可新加state进去,这就让state整体比较混沌。使用高阶组件等模式时,会造成this。props中的数据来源不透明,同样混沌。因为this魔法指针的存在,很容易挂一大堆东西上去,互相随意调用,就会让逻辑缠绕。 为了解决以上问题,React引入了Hooks:将混沌的state打散为一个个元数据。提供逻辑共享,以替代高阶组件。组件中不再存在this。 这是一种开发理念与组织理念的革新,Hooks带有强烈的3个特点:primitive、decentralization、algebraiceffects。primitive。元数据化,从最底层构建,让数据结构更清晰。同时也是一种工程趋势,比如TailwindCSS便是将CSS元数据化。decentralization。去中心化,class时代普遍是一种顶层下发的理念,但Hooks带来强烈的组件自治的理念(比如Provider不再必须,组件请求自行处理)。同时,在其他领域,去中心化也是一个大的流行概念。algebraiceffects。代数效应,归根结底,Hooks可以理解为一根管道,直通React核心能力,将内部机器暴露给了开发者。6。Hooks时代的状态管理 Hooks出现之后,社区还没有一个像Redux一样曾经一统江湖的状态管理器。 Redux添加了一些useSelector、useDispatch、useStore之类的能力,而Facebook自己也开源了Recoil这样的库。 但Redux终究老气沉沉,且早期给人留下的阴影太大,很多人的思维被格式化,随便一写就是云里雾里,只为实现一个简单功能, 而Recoil的写法则看起来有些别扭、有些啰嗦,发展也不温不火。Recoilatom({key:textState,default:});useRecoilState(textState); 而在Hooks时代,一个神秘组织异军突起,一口气贡献了3个状态管理库。 它就是pmndrs,pmndrsforPoimandres。pmnd。rs 说是组织,其实主要开发者应该是一个人,就是这位大师,DaishiKato。github。comdaishi 这三个库分别是zustand、jotai、valtio。有趣的是,这三个词其实都是状态的意思。 zustand德语状态,jotai日语状态、valtio芬兰语状态。 简单看一下用法:zustandRedux理念,旧时代精神,中心化逻辑constuseStorecreate((set)({bears:0,removeBears:()set({bears:0}),}));constbearsuseStore((state)state。bears);jotaiprimitive理念,用法略啰嗦,但符合Hooks精神constcountAtomatom(0);const〔count,setCount〕useAtom(countAtom);valtioproxy理念,不太React,但用起来简单conststateproxy({count:0,text:hello});constsnapuseSnapshot(state);7。贪婪更新vs惰性更新? 如之前提及MobX时所说,使用proxy监听的方案,虽然不够React,但确实用起来简单,且最符合直觉。 本质上来说,React是一种贪婪更新的策略,全量rerender然后diff。 而proxy是一种惰性更新的策略,可以精准知道是哪个变量更新。所以利用proxy,可以做一些rerender的性能优化。 而Reactconf上介绍的ReactForget,代表React自身也并不排斥在惰性更新的思路上做一些优化。 注意上面的贪婪更新和惰性更新是我自创的词,参考了正则中的贪婪和惰性概念。8。React状态管理思路的变迁所有state在一个大对象里分割为元数据数据不透明数据透明顶层请求,下发数据组件自身处理请求状态提升组件自治ProviderContainercomponentsjustHooks混沌集合透明解耦贪婪更新惰性更新大而全、强概念、DX更清晰、更简单、DX少一些概念,多一些直觉少一些规则,多一些自动化 总的来说,这虽是状态管理思路的变迁,但更是React社区开发思路的变迁,一种对最佳实践的不断探索:中心化去中心化数据集合元数据Buildastructure,completelyfromthegroundup9。隆重介绍resso,可能是最简单的React状态管理器 我一直在思索怎样的一个React状态管理器用起来最简单,不断去探索一个自己用起来最舒服的工具。 之前曾经开发过Retalk(Redux最佳实践)、flooks(Hooks状态管理),但随着新思路的出现,现在将最新的一些灵感集中在了resso这个状态管理库里。 下面是resso的使用方式:importressofromresso;conststoreresso({count:0,text:hello});functionApp(){const{count}store;return({count}buttononClick{()store。count}button);} 注意它与很简单的valtio相比,写法也更简单一些,应该没法更简单了,如果有,请告诉我。 更重要的是,resso会自动优化rerender,绝不因为数据在同一个对象里,就触发额外的rerender。 其实状态管理本是个很简单的东西,但Redux等工具追加了太多的复杂上去。人们用一个工具的原始目的,就是解决问题,如何而已。 所以,简单,清晰,让工具回归工具。我们了解一个锤子的方式,就是拿起来用。 希望resso会让有此需要的人喜欢。10。Investthefuture 但是这一切,又有什么用呢? 在新东西不断涌来时,人们不免会发出疑问:class组件又不是不能用,Redux又不是不能用,或者更彻底一些,jQuery又不是不能用,为什么一定要去追逐这些新的东西呢? 一个抽象的解释:我们应该不断投资未来。 这不只是在开发中,在工作中,更是在任何领域在新赛道中以不断细分的形式,用第一的身份换取资源。 旧世界的轨道上挤满了辛苦的赶路者,虽然新大陆海市蜃楼,但只有新大陆才会跃升一切。