最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React状态管理的一些思考(上篇)

    正文概述 掘金(头号前端)   2021-08-13   760

    众所周知,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,我们常常会遇到以下状态共享问题:

    1. prop drilling问题,即props传递的层级过深,我们需要手动传递props,比较麻烦。

    2. 树上距离较远的两个组件需要共享状态,在react中一个做法是,提取props到他们相邻最近的祖先节点中,回到第一种情况。

    3. 子组件向父组件传递数据,只能通过回调的方式。

    造成这些问题的根本原因还是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里使用的比较多的几个主流状态管理库的主要思想和原理。


    下载网 » React状态管理的一些思考(上篇)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元