React状态管理 | 青训营笔记

34 阅读6分钟

概述

状态管理是指将客户端和服务器的多次交互当作一个整体,将多次交互所涉及的数据状态保存下来,从而简化应用程序的状态管理。

在状态管理中,客户端和服务器需要交换一些数据,例如用户名、密码、偏好设置等。为了简化状态管理,可以将这些数据保存在数据库中,并使用状态管理技术,如cookies,在客户端和服务器之间传递这些数据。

当客户端访问服务器时,服务器可以将一些数据发送给浏览器,例如欢迎消息、登录状态等。浏览器会将这些数据保存在本地,并在下一次访问服务器时将其发送回服务器。

在状态管理中,服务器还可以使用长轮询(Long Polling)技术,通过定期发送心跳消息来检测客户端的状态。当客户端收到心跳消息时,它知道服务器仍然在运行,并可以继续与服务器通信。

本质:管理共享内存中的状态

简介

React状态管理工具可以分为以下几类:

  • React自带
  • 单向数据流
  • 双向数据绑定
  • 原子型状态管理
  • 异步操作密集型

react状态管理.png

Local State(props)

local State是组件级别的局部状态,React的数据流是自上而下的,大部分情况下local State就能满足我们的需求,但是这种向上延伸的方法,不是无限的,如果一直往上延伸,会出现一个父组件嵌套10几层子组件的情况,必须要有一个"度",超过这个"度"后,local State的方式就不太实用了。

这个"度",在前端开发中,大部分情况下我们认为就是子页面。我们一般认为,单页应用中,子页面以及子页面之下的组件都是可以用local State来解决状态管理问题的,而子页面和子页面之间,是不需要再往上延伸。子页面和子页面之间的通信,React本身提供了Context。

Context

React中的Context解决了react中, props或者state进行多级数据传递,则数据需要自顶下流经过每一级组件,无法跨级的问题。但是Context在页面间共享数据的时候同样有很多问题:

  1. Context相当于全局变量,难以追溯数据的变更情况
  2. 使用Context的组件内部耦合度太高,不利于组件的复用和单元测试
  3. 会产生不必要的更新(比如会穿透memo和dependicies等)
  4. Context 只能存储单一值,无法存储多个各自拥有消费者的值的集合。
  5. 粒度也不太好控制,不能细粒度的区分组件依赖了哪一个Context
  6. 多个Context会存在层层嵌套的问题

Redux

flux.png

redux.png Redux的三大原则:

  1. 单一数据源: 在redux中,整个应用的全局State(再次注意是全局state).都会保存在一个store中,一个单一数据源 state tree 也简化了应用的调试和和监控;它也让你在开发中能将应用数据持久化到本地,从而加速开发周期。此外,有一些功能以前很难实现,比如“撤销/重做”,在单一数据源的原则下,使用 Redux 实现将非常容易
  2. store中的State是只读的: 我们不能直接修改store中的state,store中的state是只读的。唯一能改变store中的state的方式就是通过action
  3. 使用纯函数来执行修改: 接受纯函数来接受aciton,该纯函数叫reducer,可以改变store中的state.

Redux比较适合用于大型Web项目,尤其是一些交互足够复杂、组件通信频繁的场景,状态可预测和回溯是非常有价值的。还有一种场景,比如需要事故重现,这种定义和上报事故异常和重现的场景,Redux也很有意义。

缺点:首先为了实现纯函数的Reducer,Redux必须处理各种各样的副作用,需要引入一系列的副作用中间件,加重的心智负担,此外Action,Dispatch,Reducer的模式需要写过多的样版代码,虽然通过React hooks和Redux toolkit可以减少一定的样板代码,但是复杂度还是摆在那里。因此中小项目,也不太推荐使用Redux,可能Context或者React hooks中的useReducer就能满足你的需求

Mobx

mobx.png 优点在于上手简单,可以直接修改状态,不需要编写繁琐的 Action 和 Reducer,也不需要引入各种复杂的中间件,局部精确更新,免去了粒度控制烦恼,自始至终一份引用,不需要 immutable,也没有复制对象的额外开销。因此前端数据流不太复杂的情况,使用 Mobx因为更加清晰,也便于维护。但是正是因为MobX的灵活,其代码风格很难统一。

Mobx是不能实现时间旅行和回溯的,因此不太适合前端数据流比较复杂的场景,此外,随着Reacthooks,比如useReducer等的,以及React自身的原子型状态管理工具Recoil。Mobx的使用场景会被进一步压缩目前的项目中使用Mobx的场景已经越来越小

Recoil

Recoil的核心,就是Atom原子状态,以及通过Atom原子状态可以派生出衍生状态Selector。

特点:

  1. 较为官方,提供了与 Concurrent 模式及其他 React新特性兼容的可能性,主打的是性能。此外因为其原子性的特点,比较容易做到细粒度的状态控制。也能跟Redux实现状态回溯相比较Redux而言,还有一个特点就是理解起来没有很复杂,不需要写很多样板代码等。
  2. 可以实现状态快照。比如填充首屏数据和数据状态回滚等。

Zustand

使用简单

实现一个简易的状态管理工具

发布订阅模式.png

Redux在项目中的实践

redux作为一款状态管理工具,主要为了解决组件间通信的问题

image.png

复杂: redux是遵循函数式编程的规则,上述的数据流中,action是一个原始js对象且reducer是一个纯函数,对于同步且没有副作用的操作,上述的数据流起到可以管理数据,从而控制视图层更新的目的

redux toolkit.png