当前位置: 首页 > Web前端 > HTML

Recoil是新一代React函数式编程状态管理工具

时间:2023-03-28 14:20:54 HTML

为什么要用Recoil?原因是最近重构了一个详情页,props传递层次非常深,组件间状态通信频繁。整个代码整理出来,维护难度大。重构的时候考虑一??下,细分组件,抽取数据,对数据做一个松散的管理。对比之前使用的Redux和Mobx,感觉有点重,因为项目是用纯ts+Funchooks的形式重构的,应用这两个比较常规的状态管理工具有两个缺点:项目代码相对侵入性大,需要编写大量代码。状态管理代码(dispatch、action、reducer)是一个外部库,它们无法访问React内部的调度器。主要是这两个库对于项目使用来说有点重,不是很重要的就不用了。复杂的数据管理和通信引入了不小的npm依赖项。一开始考虑用Context来处理,但是多组件订阅需要写多个Provider或者一个有根组件的Provider来访问数据,会导致很多不必要的重绘和代码量。刚刚有个同事提到了Recoil(fb自己为react提供的状态管理工具库)。看了资料觉得很适合自己的项目,就试用了一下,效果不错。Recoil简介Recoil是FaceBook提出的一种状态管理方案(个人感觉是为reactFuncComps量身打造的轻量级状态管理工具)。我们都知道React强调不变性,Recoil也强调不变性。immuteable的好处是可以提升组件的整体应用性能。关于immutable不是很清楚,建议查阅相关文档,这里就不细说了。Recoil采用原子状态去中心化管理的设计模式。Recoil提出了一个新的管理状态单元Atom(原子化),可以更新和订阅。当一个Atom被更新时,每个订阅它的组件都会随之更新。渲染,如果多个组件使用相同的Atom,那么这些组件将共享它们的状态。从上图不难看出,它的核心思想是通过订阅和发布的模型来原子地拆分数据和管理数据。使用Recoil的RecoilBasicInitializationComponents需要用RecoilRoot组件包裹}定义状态我们在上面提到了Atom的概念。Atom是一种新状态,但与传统状态不同的是,它可以被任何组件订阅。当一个Atom更新时,每个订阅的组件将使用新值重新渲染。exportconstpageInfoState=atom({key:'pageInfoState',default:{}});其中键在RecoilRoot范围内必须是唯一的。default定义默认值。订阅和更新状态useRecoilState:一个类似于useState的Hook,可以获取atom和setter函数的值。useSetRecoilState:只获取setter函数。如果只使用这个函数,状态改变不会导致组件重新渲染。useRecoilValue:只获取状态。useResetRecoilState:重置状态。import{nameState}from'./store'//useRecoilStateconstNameInput=()=>{const[name,setName]=useRecoilState(nameState);constonChange=(event)=>{setName(event.target.value);};return<>

Name:{name}
;}//useRecoilValueconstSomeOtherComponentWithName=()=>{constname=useRecoilValue(nameState);return
{name}
;}//useSetRecoilStateconstSomeOtherComponentThatSetsName=()=>{constsetName=useSetRecoilState(nameState);}returnsetName('JonDoe')}>设置名称;}//useReSetRecoilStateconstSomeOtherComponentThatSetsName=()=>{constressetName=useSetRecoilState(nameState);returnSetName;}从上面可以看出,我们使用hooks来获取和改变值,对react函数组件非常友好,代码侵入性很小.派生状态选择器代表派生状态,它允许我们构建依赖于其他原子的状态(并且还可以进行一些计算操作)。它有一个强制性的get函数,有点类似于Vue中的computed。constlengthState=selector({key:'lengthState',get:({get})=>{consttext=get(nameState);returntext.length;},});functionNameLength(){constlength=useRecoilValue(charLengthState);return<>NameLength:{length};}异步状态Recoil提供了一个数据流图来将状态和派生状态映射到React组件的方法。真正强大的特性是图中的函数也可以是异步的。这使我们可以轻松地在异步React组件渲染函数中使用异步函数。借助Recoil,您可以在选择器的数据流图中无缝混合同步和异步功能。只需从选择器获取回调中返回Promise,而不是返回值本身。例如,在下面的示例中,如果用户名存储在我们需要查询的某个数据库中,那么我们要做的就是返回一个Promise或使用一个异步函数。如果userID发生变化,将自动重新执行新的查询。结果会被缓存,所以查询只会对每个唯一的输入执行一次(所以一定要保持选择器的纯净,否则缓存的结果会和最新的值不一致)。constuserNameQuery=selector({key:'userName',get:async({get})=>{constresponse=awaitmyDBQuery({userID:get(currentUserIDState),});returnresponse.name;},});函数CurrentUserInfo(){constuserName=useRecoilValue(userNameQuery);return
{userName}
;}总结用了之后感觉Recoil的去中心化状态管理有点像observable+computed的模型。具体的源码我还没看。读了一段时间后,我将添加另一个源代码解释。在使用上,完全迎合功能组件Hooks的使用,不提供Component的使用。官方产品必须是优质产品。可以使用官方文档标榜的高性能和React内部的调度机制,包括之前承诺的并发模式,值得期待(听听就好)。主要看和自己项目的契合度。如果它适合你,你可以使用它。随着工程和项目的复杂性增加,最好选择稳定的状态管理方案。反正我打算下一阶段把Recoil放到项目里。传播经验。Recoil官方文档链接https://recoil.js.cn/