为什么不推荐使用store——React中的状态管理难题

react项目中最复杂的工作常常是状态管理问题,然而react生态相比其他框架却有着最多的状态管理库,那为什么状态管理仍然是一件非常复杂的工作呢?因为大多数的状态管理库解决的问题是跨组件数据通信的问题,并非解决状态管理复杂度,甚至他们反而会增加状态管理的复杂度。

状态与数据

react的核心理念是

Plain Text UI=render(state)

react本身可以看成一个render函数,而使用者需要负责state的管理。

拆解state的数据源,可以分为

  • serverData:服务端数据
  • localData:本地数据
  • stateData:派生出该state的其他state
  • uiData:ui数据,比如DomRect,style,以及各种事件

一般我们将state放入store中进行管理,因此从逻辑上,可以拆解为以下几个部分:

  • 业务逻辑
  • store逻辑(状态管理)
  • ui逻辑

从下图中可以看到,store中的逻辑是最复杂的,因为参与其中的数据来源最多。

一个长周期的前端项目,最先腐化的往往就是store层逻辑。

想要降低store逻辑的复杂度,就只能将其中的逻辑,划分到不同的业务Model和UI Ctrl中,让store中只处理state相关逻辑。

Redux/Zustand等状态库的缺陷

下图简单展示了这两个库是如何将数据转为状态的

上图可以看出两个特点:

  1. 无法自由改变数据------必须使用特定的方式
  2. state总是数据的拷贝------需要一直维护数据和状态的联系,且需要immer这类库

这两点反而加重了store中的逻辑复杂度。

解决方案一:Observable

React生态里,Observable方案有两大代表:Mobx和Rxjs。

Mobx方案中,所有业务Model都是state,业务Model的修改驱动试图更新

Rxjs方案中,所有state都是数据流的产物,数据流的更新驱动视图更新

虽然两者的理念/背后实现/落地形式完全不一样,但都能在一定程度上解决状态管理的复杂性------不再关心普通数据与状态数据映射和维护,数据更新即触发组件更新

解决方案二:事件驱动

假设有一个状态 x,A/B场景都修改x,但x的不同字段变更,触发的组件更新行为不一样。

举个例子:

action A 新增了一个新闻渠道,组件应该订阅该渠道,然后更新渲染。

action B 修改了某个渠道展示样式,组件应该更新该样式,但不重新订阅渠道。

如果是用redux来实现,代码可能如下:

组件并不能观察到x是被哪个场景的action修改的,因此组件不仅需要响应x的变更,而且还需要根据变更内容判断是否或如何再次更新。

数据修改和更新的流程可能如下:

不仅触发了多次更新,而且很多情况下,组件难以对数据变更进行溯源。更合理的预期是,直接响应action,而不是状态。

针对这种场景的建议方案是事件/行为驱动。组件订阅A场景的action,该订阅会给组件提供最新的x,这样组件内部就不再需要维护额外标识,也不用关心数据变更的溯源。

相关推荐
止观止30 分钟前
Remix框架:高性能React全栈开发实战
前端·react.js·前端框架·remix
萌萌哒草头将军1 小时前
🚀🚀🚀 深入探索 Node.js v22.18.0 新特性;默认支持运行 ts 文件了!
前端·typescript·node.js
安心不心安1 小时前
React ahooks——副作用类hooks之useThrottleFn
前端·javascript·react.js
秋田君1 小时前
Vue3 + WebSocket网页接入弹窗客服功能的完整实现
前端·javascript·websocket·网络协议·学习
浪里行舟1 小时前
一网打尽 Promise 组合技:race vs any, all vs allSettled,再也不迷糊!
前端·javascript·vue.js
Antonio9152 小时前
【网络编程】WebSocket 实现简易Web多人聊天室
前端·网络·c++·websocket
tianzhiyi1989sq3 小时前
Vue3 Composition API
前端·javascript·vue.js
今禾3 小时前
Zustand状态管理(上):现代React应用的轻量级状态解决方案
前端·react.js·前端框架
用户2519162427113 小时前
Canvas之图形变换
前端·javascript·canvas
今禾3 小时前
Zustand状态管理(下):从基础到高级应用
前端·react.js·前端框架