众所周知,react可以抽象为一个函数: UI = render(data)
。这意味着我们可以专注于构建data,而不用考虑如何更新视图。
但随着SPA(single page application)单页面应用复杂度的提高,状态也会变大,管理状态的难度也会增加。
为了更好的管理应用的状态,或许会考虑状态使用react状态管理的库,但是该考虑和如何选择?
状态
首先我们要知道什么是状态,举个例子:当我们和我们的应用交互的时候,比如我们点击了一个button,会弹一个对话框,或者UI会有变化,或者发送一个请求。 随着点击事件,我们的应用有对应的响应。可以肯定的是这个时刻的 状态 跟点击之前的不一样了,我们应用进入了一个新的状态。比如说标志是否打开弹窗的变量、AJAX请求的数据,这些变量我们都可以称之为状态。 广泛的讲,应用的状态就是这些变量。它可以是React中使用useState(函数组件)或者this.state(类组件)保存的数据,也可以保存第三方状态管理库里。
抉择
在React中如果我们需要储存状态,我们一般会选择以下三种途径方式:
-
储存在当前组件里面,函数组件里面可以使用useState、useReducer这些hooks,类组件可以存在this.state里面。
-
储存在第三状态管理库的仓库(store)里,相关的库有:Redux、MobX、Recoil....
-
自己维护状态,例如我们可以直接存在window里。。。
相应的如果改变状态,我们可以:
-
当我们调用useState、useReducer、this.setState的时候,React将会自动重新渲染,这是React提供给我们的机制。
-
如果我们使用第三方库,例如Redux、MobX、Recoil等。。。他们会在适当的时机,然后调用Ract的API触发重新渲染。
-
如果自己维护了数据,例如保存在window里,就需要自己实现状态改变触发重新渲染的逻辑,但是不建议。 其实react并不在意你把数据放在哪,react处理的只是data -> UI的映射。
在绝大多数情况下,我们使用React提供的组件级别的状态管理API就完全足够了。
简单状态共享场景
但是其实如果我们只用React提供的API,我们常常会遇到以下状态共享问题:
-
prop drilling问题,即props传递的层级过深,我们需要手动传递props,比较麻烦。
-
树上距离较远的两个组件需要共享状态,在react中一个做法是,提取props到他们相邻最近的祖先节点中,回到第一种情况。
-
子组件向父组件传递数据,只能通过回调的方式。
造成这些问题的根本原因还是React的 单向数据流 的设计思想,React恨不得把所有状态都保存在顶层。 当然单向数据流的设计有利有弊,好处就是每个组件的依赖(数据流入)都很清晰,坏处就是状态共享问题。 于是,React提出了Context API。但是我们需要明确的是 Context API解决的其实是依赖注入的问题 ,它本身并不是状态管理工具,具体可以看看这篇 Blogged Answers: Why React Context is Not a "State Management" Tool 事实上有基于Context API + Hooks封装库。 jamiebuilds/unstated-next , 源码 十分简单。 看过源码也就能发现,其实是会有性能问题的,更改状态后,所有使用context的组件都会重新渲染。所以他们只适用于需要快速上手、对性能要求不高的 简单场景 。
网络密集型的场景
这种场景常见于中后台项目,需要频繁从服务端请求数据,请求后的数据需需要进行加载状态、缓存和过期管理,这种场景可以使用React-query或者SWR。 以React-query特性来说:
-
使用hooks API
-
封装了许多前端异步请求的逻辑
-
数据缓存控制,自动更新数据
-
重复请求合并
-
分页和延迟加载
-
。。。
复杂场景
我觉得可能真正的 复杂场景 有:
-
用户的使用方式复杂
-
不同身份的用户有不同的使用方式(比如普通用户和管理员)
-
多个用户之间可以协作
-
与服务器大量交互,或者使用了WebSocket
-
View要从多个来源获取数据
-
。。。
总而言之,在多状态、多交互、多数据源、数据耦合等复杂场景中,就需要使用 复杂状态管理库 。 按照设计思想,可以大概把他们分为四类:
-
单向数据流:Redux, Zustand
-
响应式数据流/Proxy:Mobx, Valtio
-
原子模式Atomic:Recoil, Jotai
-
Stream: rxjs(Reactive Extension JavaScript)
这里要说一下Redux、Mobx等都是比较偏底层的并且是框架无关的,他们常常有框架关联的库如react-redux,mobx-react。
总结
在React生态里面,状态管理的库有很多,我们需要根据自己的需求选择适合业务场景的状态管理库。 接下来的文章将会介绍React里使用的比较多的几个主流状态管理库的主要思想和原理。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!