React 状态管理11 | 青训营笔记

65 阅读4分钟

什么是状态管理

从React诞生之后,前端组件化的方案深入人心,React遵循的是单向数据流的原则,属性通过Props自 上而下的传递。当页面的比较简单,组件之间的层级关系比较浅时,这种自上而下的单向数据流的方式是 不会有问题的。如果页面一复杂,组件的嵌套层级一深,这种单向数据流的传递方式,将会使你陷入到“嵌套地狱”。

状态管理本身,解决的就是这种“嵌套”地狱的问题,解决的是跨层级组件之间的数据通信和状态共享。

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

  1. 共享内存
  2. 管理状态
  3. 页面通信
  4. 组件通信
  5. 刷新失效?

详细定义: 单页应用的各个组件本身是共享内存的,如果将状态保存在内存中,就可以读写统一内存中的变量,从而达到状态共享的目的。

为什么React有这么多状态管理工具?

  • Vue: Vuex(Pinia)
  • Angular: Service和Rxjs
  • React: Flux、Redux、Mobx、Rxjs、Recoil、Jotai、Zustand

跟不同前端框架的定义有关,Vue和Angular双向数据绑定,计算属性等,数据是响应式的, 控制视图刷新,拥有计算属性等,这些使得Vue和Angular需要状态管理的场景减少,此外其 本身就包含了完整的状态管理工具,比如Vue的Vuex和Pinia,Angular的Service(RXjs)等,从官方定调。而React不一样, React是一个纯UI层的前端框架,UI = fn(state),React将状态的变动完全交给开发者。

状态管理管理工具简介

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

  • React自带:Local State(props)和Context
  • 单向数据流:Flux、Redux(Redux-toolkit)
  • 双向数据绑定:Mobx
  • 原子型状态管理:Recoil、Jotai
  • 异步操作密集型:Rxjs

每一种状态管理工具都有其不同的适用性,不同场景下需要合理的选择状态管理工具。

Context

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

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

Redux

Redux是从Flux演变而来的 Flux它是Facebook官方给出的应用架构,利用数据的单向流动的)式对公共状态进行管理。

Flux利用数据的单向流动的形式对公共状态进行管理。

  • View:视图层
  • Action:视图发出的消息
  • Dispatcher:派发者,用来接收Action,执行回调函数
  • Store:数据层,存放状态,一旦发生改动,就会更新数据以及emit相关事件等

Flux的缺点:

  1. UI组件和容器组件的拆分过于复杂
  2. Action和Dispatcher绑定在一起
  3. 不支持多个store
  4. store被频繁的引入和调用

Redux的三大原则:单一数据源,只有一个store、store中的state是只读的、使用纯函数来执行修改。

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

收获: 通过本次课程的学习,了解了状态管理工具以及根据不同的场景如何选择状态管理工具。