当前位置: 首页 > 科技观察

讨论:Redux这么有名,我们却不适合

时间:2023-03-21 12:47:44 科技观察

说起React状态管理方案,很多人的第一反应就是Redux。为什么Redux如此出名,个人观点,2个原因:它出现的早,当时社区还没有更好的状态管理方案,有React核心团队的加持。Redux作者“Dan”在开发出第一版Redux后加入了React团队。另一位合著者“Andrew”也来自React核心团队。Dan的适时出现和名气,催生了Redux相关生态在社区的快速发展,也成为了很多前端团队的标配。谈到状态管理,你通常会谈些什么?谈到“状态管理”,通常会从“广度”和“深度”两个方面来谈。从广度上来说,它之后出现的解决方案似乎都在对标Redux,提出自己独特的解决方案。例如:对比Redux的单向数据流,Mobx使用双向数据绑定对标Redux的“全局状态”概念,recoil提出“原子状态”的概念。在深度上,Redux社区不断扩大,并且基于Redux的中间件应运而生。比如Redux-Saga。在中间件之上,出现了更全面的解决方案,比如基于Redux-Saga的DVA。除了这两个纬度之外,还有其他的视角吗?其实我们可以从问题的本质入手。前端,需要什么状态?从页面交互的角度来看,状态的来源有两种:IO操作缓存数据用户交互的中间状态IO操作缓存数据前端最常见的IO操作就是向服务端请求数据。如果不使用“状态管理”方案,常见的方式是请求数据并保存在组件状态中,如:functionApp(){const[data,updateData]=useState(null);useEffect(()=>{fetchData('/api/user').then(data=>updateData(data))},[])//处理数据}当使用Redux等“状态管理”解决方案时,请求的数据将被序列化并保存在“全局状态”中间。用户交互的中间状态交互的中间状态,如isLoading和isOpen,也存储在组件内部。当是一个可重用的组件,或者状态需要跨组件层级传递时,通常会用到ContextAPI。更广泛的州将使用“州管理”方案。可见,无论是“IO操作缓存的数据”还是“用户交互的中间状态”,常规的解决方案是:一视同仁。这又回到了讨论“广度”(使用哪个状态)和“深度”(使用这个状态管理解决方案的深度)。但实际上,这两种状态的特点是不同的。处理缓存的状态管理对于第一种情况,无论是服务器请求,localStorage,indexedDB,本质上都可以归为缓存。因此,相比于Redux等常规的状态管理方案,缓存处理方案可能更适合。对于缓存,常见的需求是:数据状态、加载?加载完成?发生错误?缓存失效后更新缓存数据的复用在React技术栈中,SWR和react-query是优秀的解决方案。这里有一个SWR的例子:对于刚才的例子:functionApp(){const[data,updateData]=useState(null);useEffect(()=>{fetchData('/api/user').then(data=>updateData(data))},[])//处理数据}SWR使用useSWR解决方案:functionApp(){const{data,error}=useSWR('/api/user',fetcher)if(error)return

failedtoload
if(!data)return
loading...
return
hello{data.name}!
}下面看看SWR是如何满足以上三个需求的:数据状态:通过useSWR的返回值参数判断请求状态。例如,!error&&!data表示“请求”。缓存失效后更新:SWR本身是stale-while-revalidate的缩写,一种基于RFC5861[1]的缓存更新策略。复用缓存数据:SWR会以请求url为key,对应的promise为value来缓存数据,从而达到多次重复请求复用缓存的目的。处理用户交互的状态管理针对“用户交互”的状态管理需求,如:全局模态切换状态、页面皮肤切换。我们可以根据项目类型和复杂程度选择合适的状态管理方案。横向上,不同类型的项目适合不同的状态管理:前端逻辑重的工具类项目(比如富文本编辑器)需要完整的redo和ondo逻辑。Redux的“单向不可变数据流”是独一无二的选择。后台管理系统,逻辑不复杂,但繁琐。那么Mobx的“双向数据绑定”开发效率可能会更高。从纵向来看,我们需要考虑项目的复杂性:类似于官网、逻辑不复杂的SPA、个人项目,“完全没有必要”使用额外的状态管理方案。本机ContextAPI是您的最佳选择。对于需要小团队协作的项目,如果复杂度不高,ContextAPI可以满足所有需求,但是需要稍微写一些规范来约束团队成员。这时候可以选择Unstated[2]Unstated的核心代码只有40行,给项目带来标准化的状态管理约束,不引入额外的学习成本。只有对于更复杂的项目,才应该考虑Redux和Mobx等解决方案。.总结“状态管理”方案的选择,我们可以按照以下原则进行选择:区分“缓存”和“用户交互”对应的状态,区别对待“用户交互”的状态,选择合适的解决方案Redux根据项目类型和复杂度很好,但是不要滥用~参考文献[1]RFC5861:https://tools.ietf.org/html/rfc5861[2]Unstated:https://github.com/jamiebuilds/未说明