react数据流分类
- 没有状态管理工具:直接用 React原生的 props 或者 useContext
- 单项数据流:第一代的 redux、第二代的 zustand
- redux思想
- dva
- rematch
- redux-saga
- reactQuery,管理服务端全局状态管理
- react toolkit管理客户端全局状态
- 为了减少 redux 的复杂和样板代码推出的
- redux思想
- 双向数据绑定:mobx、valtio
- umi4x 推荐使用 valtio,放弃之前的 dva connect数据流
- valtio是以 Proxy为核心的状态管理库
- 数据Data 与视图 View 分离的心智模型
- 状态原子化:jotai、recoil,hox
- Facebook 状态管理库Recoil,解决 context 状态的传导需要过多的provider 嵌套的问题
- hox 通过hook来复用,Rcoil的使用方式需要两个API的组合,较为繁琐
- 有限状态机:xstate
- Fetch-on-Render 请求瀑布,下一个请求要等上一个请求结束
全局数据流
重写数据流往往意味着代码完全重构,
选择一个适合自己数据流,不要混合使用,造成心智负担;
https://osawards.com/react
全局数据流的场景比如:登录、通知、当前用户信息等
数据和 ui 解耦,以及由此带来的心智变化,比如拿到设计交付后,分开设计、开发和测试数据层和视图层,最后做结合
数据流方案选择
心智模型、读取数据、写入数据、数据推导、异步 Action、渲染性能优化、Suspense 并发模式支持、SSR 支持、React 之外访问、组件封装、瞬时更新、插件中间件扩展、Redux DevTools 支持、兼容性、多实例和单实例、数据序列化能力、同步/异步更新、内存管理、测试、包尺寸等。
外部 store 以数据为中心,设计应用时设计的是数据,从数据角度出发,无需考虑组件,从上到下地组织,比如 Redux、Dva、Zustand 等都属于这类
内部 store 以 React 组件为中心,设计应用时以组件为主,从下到上原子化的组织(原子是一个最小但完整的状态单位,它们是小块的状态,可以连接在一起形成新的派生状态,最终形成了一个图
基于 proxy 的通常是 mutable
selector 非常依赖开发者素质,select 多了就可能会导致不必要的渲染
数据流管理总结
重写数据流往往意味着代码完全重构,所以,选择一个适合自己数据流,不要混合使用,造成心智负担;
单项数据流、双向绑定、状态原子化 本质上都是发布订阅模式;
数据状态管理,核心要解决的是:组件之间跨层级通信,和数据共享
- 去中心化,不要集中式管理
- 元数据
- 细粒度 render
- 可预测,渐进式
- 如果状态有复杂数据流的处理,请用 rxjs
使用 react带来的问题
- 状态管理混乱
- 组件层级较深时,跨组件数据层层传递 props
- 一个数据改变,带来整个页面的刷新
- 组件数据,行为,UI耦合在一起
- 单页面应用中,全局状态需要管理,且多个页面依赖整个数据,可能修改全局数据,引起不必要的渲染
props 数据流
props应用场景
小型的项目,且没有多少状态需要共享,不需要状态管理,react 本身的 props 或者 context 就能实现需求
状态提升
状态提升 → 组件自治
如果有2个同级组件,要共享一个状态,
需要把状态存放到他们共同的父组件里面,最近的父组件
然后通过属性props 向下传递数据
props drilling 问题
useContext
项目大会有性能问题,每一次对 props 的变更都会引起全局的渲染,
可以用 memo 解决一部分性能问题
immutable 不可变数据
不推荐用 redux-immutable 以及 redux-immutablejs,
一是没啥必要,具体看他们的实现就知道了,都比较简单;
更重要的是他们都改写了 combineReducer,会带来潜在的一些兼容问题
https://github.com/sorrycc/blog/issues/1
不熟悉 immutable.js 的可以先尝试用 seamless-immutable,JavaScript 原生接口,无学习门槛
双向数据绑定
valtio
使用体验和 mobx 基本一致,双向绑定的状态管理首选
valtio 特点
- 细粒度 render
- 计算属性
- 非 react 上下文订阅和更新
缺点
typescript 类型推断功底不太好
mobx
mobx https://cn.mobx.js.org/intro/overview.html
redux 数据流思想
redux核心概念
action,dispatch,connect,reducer,store,useStore,Provider,Context
集中式数据管理
- store的连接与订阅
- 一个独立的 store,解决数据共享问题
- action
- reducers
- react-redux
- redux-thunk
- 自定义redux中间件
zustand
缺点:不支持计算属性
xstate 有限状态机
使用有限状态机来进行状态管理,适用于对于复杂业务逻辑的状态管理,
例如,电商中订单的状态有
- 待付款
- 待发货
- 待收货
- 待评价
- 交易完成
- 用户取消
- 仅退款
- 退货退款
管理的是复杂的业务状态,可以使用有限状态机做状态的跳转管理,
通过有限状态机来维护这些状态,每个状态又都可以通过某些 action 进行状态转移
状态原子化 rcoil & hox
两个或多个组件之间简单的数据共享,那么原子化或许是合适的选择
hox和Rcoil特点
- Flexible shared state: 在 react tree 任意的地方都能灵活共享 state
- Derived data and queries: 高效可靠地根据变化的 state 进行计算
- App-wide state observation: time travel debugging, 支持 undo, 日志持久化
hox
https://github.com/umijs/hox
中文文档 https://hox.js.org/zh/
hox特点
- 没发做到细粒度渲染(需要手动控制依赖项才能细粒度更新)
- 计算属性的支持很别扭
- 只能在 react 上下问中才能使用
Recoil
Recoil里需要一个额外的初值,和一个额外的selector 才能实现
非react上下文订阅、操作状态的需求
缺点
- 无法在非 react 上下问中使用,和 react、 react-dom 强绑定
jotai
缺点
- 处理异步时很麻烦
- 无法在非 react 上下问中使用
- 如果是简单的两个组件之间的简单的数据共享,jotai可能是合适的工具
react数据流库参考
react状态管理选哪个? - 知乎