You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importReactfrom"react"importReactDOMfrom"react-dom"import{makeAutoObservable}from"mobx"import{observer}from"mobx-react"// Model the application state.classTimer{secondsPassed=0constructor(){makeAutoObservable(this)}increase(){this.secondsPassed+=1}reset(){this.secondsPassed=0}}constmyTimer=newTimer()// Build a "user interface" that uses the observable state.constTimerView=observer(({ timer })=>(<buttononClick={()=>timer.reset()}>Seconds passed: {timer.secondsPassed}</button>))ReactDOM.render(<TimerViewtimer={myTimer}/>,document.body)// Update the 'Seconds passed: X' text every second.setInterval(()=>{myTimer.increase()},1000)
importReactfrom'react';import{RecoilRoot,atom,selector,useRecoilState,useRecoilValue,}from'recoil';functionApp(){return(<RecoilRoot><CharacterCounter/></RecoilRoot>);}consttextState=atom({key: 'textState',// unique ID (with respect to other atoms/selectors)default: '',// default value (aka initial value)});functionCharacterCounter(){return(<div><TextInput/><CharacterCount/></div>);}functionTextInput(){const[text,setText]=useRecoilState(textState);constonChange=(event)=>{setText(event.target.value);};return(<div><inputtype="text"value={text}onChange={onChange}/><br/>
Echo: {text}</div>);}constcharCountState=selector({key: 'charCountState',// unique ID (with respect to other atoms/selectors)get: ({get})=>{consttext=get(textState);returntext.length;},});functionCharacterCount(){constcount=useRecoilValue(charCountState);return<>Character Count: {count}</>;}
背景
由于要做一个使用起来比较舒服的轮子,最近研究了下React的状态管理库,当然,仅限在使用层面,也就是用着舒服的角度来选择到底使用哪个状态管理库。本着在Github上面看看React社区内状态管理库的流行程度和使用程度的层面,来进行选型,然后就有了这篇文章,关于我们最后选择了哪个,文章末尾告知。
选择库的原则如下:
截止目前为止,在Github上面看了一下当前比较流行的几个状态管理库的star数和used by的数量,以及npm上面的周下载量(weekly downloads),这可以从某些方面说明明该框架的受欢迎程度,也有很小的可能性不准确,不过很大程度上,对框架选型是有所帮助的。
上面表格中,就是我们接下来要进行挑选的对象,到底中意哪个,还得看看使用起来的时候的姿势,哪个更加舒服。
mobx
mobx是一个非常优秀的react状态管理库,这毋容置疑,而且在Github上面,它的使用量也是做到了第一,官方文档地址zh.mobx.js.org。官网上面给的例子是非常简单的,大多数官网也都如此,可是我不需要简单的例子,我需要一个完整的项目的例子,于是参考了github上面的一个项目antd-pro-mobx。mobx需要搭配mobx-react的连接库一起来使用。
按照npm上面的推荐是要使用class + observe函数包裹的方式,最新版本v6:
新项目的从头开始,应该不会选择老版本的库区使用,一般会选择稳定的新版本的进行使用,关于typescript方面,看源码是已经在使用typescript来编写了,不过在官网和npm上面并没有看到typescript的蛛丝马迹,可能是还没发版吧。
我们对比我们的原则看下关于mobx:
关于mobx部分就暂且到这,说的不对的地方欢迎告知,确实是才疏学浅,没怎么用过这么流行的状态管理库。
reduxjs/toolkit
toolkit,暂且这么叫吧,redux官方状态管理库,cra模板redux(
npx create-react-app --template redux
)自带状态管理库,cra模板redux-ts(npx create-react-app --template redux-typescript
)自带状态管理库.可能这两个模板也导致了toolkit的下载量和使用量非常大。也由于是redux官方库的原因,需要搭配react-redux来搭配使用。这些我们暂且不管,我们看下如何使用,亲测哈,如有使用不当,可以指出。上面是主入口文件的代码,可以看到这个使用方式还算是比较普遍,符合redux的使用方式。
上面是store主文件的代码,这其实也是官方给出的合理使用方式。
上面是在实际module的使用,会产出一个reducer,唯一不优雅的地方在于
extraReducers
的调用方式采用了串联的方式,不过还可以通过对象的形式进行传递,不过在ts中支持不够友好,如下:可以看到上面换成了对象的方式,不过在函数里面需要自己去写好类型声明;而串行的方式,typescript已经自动推导出了函数所对应的参数类型。
我们对比我们的原则看下关于toolkit:
recoil
recoil,react官方状态管理库,随着react17而来,官方网址为recoiljs.org,其实透过官方文档,我们可以看到差不多是完全遵循了react hooks的使用方式,不需要搭配任何连接器,可以与react直接无缝连接。不过这其实也导致了原子性比较强,统一的状态管理需要对其进行二次封装,而且工作量不小。在typescript方面,0.3.0开始支持,当前为止最新的版本是0.3.1。例子我就看下官方的例子
由上面,我们可以简单再对比下我们的原则:
zustand
zustand,这个库,说实话,是第一次看到,不过看了npm上面的例子,这个库还是很好用&很实用的,使用起来很舒服,提供的api不是很多,但是够精简,能够满足需求。没有单独的官网,不过readme写的足够详细,算是个地址吧npm zustand, 我们来看下官网提供的例子:
可以看到所有的数据使用的createStore进行包裹,里面可以定义任意类型,可以是count的这样的stats类型,也可以使用函数(包括异步函数),做到了最简单化;另外zustand还提供了一些其他的工具函数和中间件,关于中间件和工具函数等的如何使用,此处就不多说了,可以去npm看看.
由上面,我们可以简单再对比下我们的原则:
rematch
rematch, 因为有部分项目在使用这个库,所以简单看了下使用。官网上面有很多例子,可以去看看: rematchjs.org. v1的时候是不支持typescript的,使用上有两种方式(对于effects)
v2的时候是增加了typescript的支持,不过却去掉了上面方式一的使用方式,只保留了第二种。具体例子可以前往rematch typescript 查看。这个使用方式其实与上面的redux-toolkit稍微有点相似,不过好像rematch最近下载量下降了不少。
rematch在模块化封装部分做的很好,能够对所有的状态进行统一管理,然后可以按models进行划分功能,使用起来比较舒服。
由上面以及官网上面的一些例子,我们可以简单再对比下我们的原则:
concent
concent,另外一种状态管理器的实现方式,在使用上与Vue3的setup有很大相似之处。为什么会谈到concent,因为有好几个项目在使用concent,而且表现良好。官方网站concentjs.concent功能非常强大,各种黑魔法,要想使用好concent,会有比较大的学习成本,也就是使用起来可能不会很简单。
完整的例子和api可以前往官网查看,支持class装饰器的模式,也支持函数setup的方式,也有不使用setup的方式,都能满足;问题就是api较多,学习成本较高。
根据经验和上面的例子,我们可以简单再对比下我们的原则:
结论
至此,这几种状态管理库的使用方式和原则对比差不多已经完成。可能有使用不当或者说明错误的地方,欢迎指出。
最终我们考虑了以下几点:
最终选择的是redux官方的toolkit来进行统一的状态管理。
本文结束,感谢阅读,欢迎讨论交流。如有不当之处感谢指出。
关注
欢迎大家关注我的公众号[
德莱问前端
],文章首发在公众号上面。除每日进行社区精选文章收集外,还会不定时分享技术文章干货。
希望可以一起学习,共同进步。
The text was updated successfully, but these errors were encountered: