状态管理之 Flux、Redux、Vuex、MobX(概念篇)
本文是对 Flux、Redux、Vuex、MobX 几种常用状态管理模式的总结,偏向于概念层面,不涉及过多代码。
状态管理
什么是状态管理?
状态管理就是,把组件之间需要共享的状态抽取出来,遵循特定的约定,统一来管理,让状态的变化可以预测。
为什么需要状态管理?
状态共享
组件之间通常会有一些共享的状态,在 Vue 或者 React 中我们一般会将这部分状态提升至公共父组件的 props 中,由父组件来统一管理共享的状态,状态的改变也是由父组件执行并向下传递。这样会导致两个问题:
- 需要将共享的状态提升至公共的父组件,若无公共的父组件,往往需要自行构造
 - 状态由父组件自上而下逐层传递,若组件层级过多,数据传递会变得很冗杂
 
变化跟踪
在应用调试过程中,可能会有跟踪状态变化过程的需求,方便对某些应用场景的复现和回溯。这时候就需要统一对状态进行管理,并遵循特定的约定去变更状态,从而让状态的变化可预测。
Store 模式
Store 模式是一种相对简单的状态管理模式,一般有以下约定:
- 状态存储在外部变量 
store里(也可以是全局变量) store中的state用于存储数据,由store实例维护stor中的actions封装了改变state的逻辑
流程图如下:
如果对 state 的变更均通过 actions,那么实现记录变更、保存快照、历史回滚就会很简单,但是 Store 模式并没有对此进行强制约束。
Flux
Flux 是一种架构思想,类似于 MVC 、MVVM 等。
Flux 的组成
Flux 把一个应用分成四部分:
- View:视图层
 - Action:动作,即数据改变的消息对象(可通过事件触发、测试用例触发等)
- Store 的改变只能通过 Action
 - 具体 Action 的处理逻辑一般放在 Store 里
 - Action 对象包含 type (类型)与 payload (传递参数)
 
 - Dispatcher:派发器,接收 Actions ,发给所有的 Store
 - Store:数据层,存放应用状态与更新状态的方法,一旦发生变动,就提醒 Views 更新页面
 
Notice:
- Action 本质上是一个纯声明式的数据结构,仅提供对事件的描述,不提供事件的具体逻辑。通常会给 Action 的 
type属性赋值一个大写的字符串,表明是常量,增强可维护性,例如: 
{
  type: 'ADD_USER',
  payload: {
    name: 'user_name'
  }
}
复制代码
Flux 的特点
- 单向数据流。视图事件或者外部测试用例发出 Action ,经由 Dispatcher 派发给 Store ,Store 会触发相应的方法更新数据、更新视图
 - Store 可以有多个
 - Store 不仅存放数据,还封装了处理数据的方法
 
Redux
Redux 的组成
- Store:存储应用的状态 -- 
state以及用于触发state更新的dispatch方法等,整个应用仅有单一的 Store。Store 中提供了几个管理state的 API:store.getState():获取当前 statestore.dispatch(action):触发state改变(唯一途径)store.subscribe(listener):设置state变化的监听函数(若把视图更新函数作为 listener 传入,则可触发视图自动渲染)
 - Action:同 Flux ,Action 是用于更新 state 的消息对象,由 View 发出
- 有专门生成 Action 的 Action Creator,其本质上是一个返回 Action 对象的函数
 
 - Reducer:是一个根据 
action.type更新state并返回nextState替换原来的state的同步的纯函数(对于相同的参数返回相同的返回结果,不修改参数,不依赖外部变量)。即通过应用状态与 Action 推导出新的 state:(previousState, action) => newState。Reducer 返回一个新的 state 
整体流程为:Action Creator => action => store.dispatch(action) => reducer(state, action) => state = nextState。流程图如下:
Middleware
Redux 还支持中间件,用于管理异步数据流。
Redux 的 Middleware 是对 store.dispatch() 进行了封装之后的方法,可以使 dispatch 传递 action 以外的函数或者 promise;通过 applyMiddleware 方法应用中间件。(middleware 链中的最后一个 middleware 开始 dispatch action 时,这个 action 必须是一个普通对象)
常用库:redux-actions, redux-thunk, redux-promise 。
const store = createStore(
  reducer,
  // 依次执行
  applyMiddleware(thunk, promise, logger)
)
复制代码
Redux 的特点
- 单向数据流。View 发出 Action (
store.dispatch(action)),Store 调用 Reducer 计算出新的 state ,若 state 产生变化,则调用监听函数重新渲染 View (store.subscribe(render)) - 单一数据源,只有一个 Store
 - state 是只读的,每次状态更新之后只能返回一个新的 state
 - 没有 Dispatcher ,而是在 Store 中集成了 dispatch 方法,
store.dispatch()是 View 发出 Action 的唯一途径 - 支持使用中间件(Middleware)管理异步数据流
 
Vuex
Vuex 是 Vue 的状态管理模式。
Vuex 的核心概念
- Store:Vuex 采用单一状态树,每个应用仅有一个 Store 实例,在该实例下包含了 state, actions, mutations, getters, modules
 - State:Vuex 为单一数据源
- 可以通过 
mapState辅助函数将 state 作为计算属性访问,或者将通过 Store 将 state 注入全局之后使用this.$store.state访问 - State 更新视图是通过 vue 的双向绑定机制实现的
 
 - 可以通过 
 - Getter:Getter 的作用与 filters 有一些相似,可以将 State 进行过滤后输出
 - Mutation:Mutaion 是 vuex 中改变 State 的唯一途径(严格模式下),并且只能是同步操作。Vuex 中通过 
store.commit()调用 Mutation - Action:一些对 State 的异步操作可以放在 Action 中,并通过在 Action 提交 Mutaion 变更状态
- Action 通过 
store.dispatch()方法触发 - 可以通过 
mapActions辅助函数将 vue 组件的 methods 映射成store.dispatch调用(需要先在根节点注入 store) 
 - Action 通过 
 - Module:当 Store 对象过于庞大时,可根据具体的业务需求分为多个 Module ,每个 Module 都具有自己的 state 、mutation 、action 、getter
 
Vuex 的特点:
- 单向数据流。View 通过 
store.dispatch()调用 Action ,在 Action 执行完异步操作之后通过store.commit()调用 Mutation 更新 State ,通过 vue 的响应式机制进行视图更新 - 单一数据源,和 Redux 一样全局只有一个 Store 实例
 - 只能应用于 Vue
 
MobX
MobX 背后的哲学是:
任何源自应用状态的东西都应该自动地获得。
意思就是,当状态改变时,所有应用到状态的地方都会自动更新。
MobX 的核心概念
- State:驱动应用的数据
 - Computed values:计算值。如果你想创建一个基于当前状态的值时,请使用 computed
 - Reactions:反应,当状态改变时自动发生
 - Actions:动作,用于改变 State
 - 依赖收集(autoRun):MobX 中的数据以来基于观察者模式,通过 autoRun 方法添加观察者
 
举个栗子:
const obj = observable({
  a: 1,
  b: 2
})
autoRun(() => {
  console.log(obj.a)
})
obj.b = 3 // 什么都没有发生
obj.a = 2 // observe 函数的回调触发了,控制台输出:2
复制代码
MobX 的特点
- 数据流流动不自然,只有用到的数据才会引发绑定,局部精确更新(细粒度控制)
 - 没有时间回溯能力,因为数据只有一份引用
 - 基于面向对象
 - 往往是多个 Store
 - 代码侵入性小
 - 简单可扩展
 - 大型项目使用 MobX 会使得代码难以维护
 
总结
- Flux 、Redux 、Vuex 均为单向数据流
 - Redux 和 Vuex 是基于 Flux 的,Redux 较为泛用,Vuex 只能用于 vue
 - Flux 与 MobX 可以有多个 Store ,Redux 、Vuex 全局仅有一个 Store(单状态树)
 - Redux 、Vuex 适用于大型项目的状态管理,MobX 在大型项目中应用会使代码可维护性变差
 - Redux 中引入了中间件,主要解决异步带来的副作用,可通过约定完成许多复杂工作
 - MobX 是状态管理库中代码侵入性最小的之一,具有细粒度控制、简单可扩展等优势,但是没有时间回溯能力,一般适合应用于中小型项目中
 
参考:
作者:jeff_
链接:https://juejin.im/post/5de77800518825125503ec27
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
状态管理之 Flux、Redux、Vuex、MobX(概念篇)的更多相关文章
- Redux/Mobx/Akita/Vuex对比 - 选择更适合低代码场景的状态管理方案
		
近期准备开发一个数据分析 SDK,定位是作为数据中台向外输出数据分析能力的载体,前端的功能表现类似低代码平台的各种拖拉拽.作为中台能力的载体,SDK 未来很大概率会需要支持多种视图层框架,比如Vue2 ...
 - 前端MVC Vue2学习总结(九)——Vuex状态管理插件
		
一.概要 1.1.Vuex定义与注意事项 Vuex是为vue.js框架更好的管理状态而设计一个插件.Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的 ...
 - vue总结 08状态管理vuex
		
状态管理 类 Flux 状态管理的官方实现 由于状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue 提供 vuex:我们有受到 Elm 启发的状态管 ...
 - 了解Vuex状态管理模式的理解强化指南
		
1 Vuex是什么呢?它是Vue的状态管理模式,在使用vue的时候,需要在vue中各个组件之间传递值是很痛苦的,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被改变,所有引用该值的地 ...
 - Vuex状态管理总结
		
一.什么是 Vuex 1.Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 2.Vuex 采用集中式存储和管理应用中所有组件的状态 3.Vuex 应用的核心是 store(仓库)-- 包 ...
 - vue状态管理vuex从浅入深详细讲解
		
1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...
 - VueX状态管理器 的应用
		
VueX状态管理器 cnpm i vuex axios -S 1 创建Vuex 仓库 import Vue from 'vue' import Vuex from 'vuex' vue.use(Vue ...
 - Mobx-React : 当前适合React的状态管理工具
		
MobX 简单.可扩展的状态管理 MobX 是由 Mendix.Coinbase.Facebook 开源和众多个人赞助商所赞助的. 安装 安装: npm install mobx ...
 - React的状态管理工具
		
Mobx-React : 当前最适合React的状态管理工具 MobX 简单.可扩展的状态管理 MobX 是由 Mendix.Coinbase.Facebook 开源和众多个人赞助商 ...
 
随机推荐
- iOS  中通过kvc  获取数组的均值、求和、最大最小值等
			
NSArray *values = @[@, @, @, @, @, @, @, @, @, @, @, @, @, @, @, @, @]; NSNumber *avg = [values valu ...
 - Aizu - 1383 Pizza Delivery (最短路图+DAG上的割边)
			
题意:给出一张有向图,每条边有长度,对于每条边,你要回答将该边的方向取反后,从起点到终点的最短距离是增加or减小or不变. 首先求出起点到所有点的最短距离和所有点到终点的最短距离(两次DIjkstra ...
 - eclipse找不到JadClipse问题
			
版本信息: Eclipse Java EE IDE for Web Developers. Version: 2018-09 (4.9.0) 根据以往配置,放在eclipse\plugins下不生效, ...
 - php上传大文件的解决方案
			
1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...
 - ActiveMQ介绍
			
一.背景 中间件 由于业务的不同.技术的发展.硬件和软件的选择有所差别,导致了异构组件或应用并存的局面.要使这些异构的组件协同工作,一个有效的方式就是提供一个允许它们进行通信的层,该层即为中间件. 在 ...
 - tensorboard 远程服务器本地浏览器无法显示
			
在用xshell等ssh工具远程连接服务器时,我们常常在服务器上运行tensorflow代码,而且模型tf.summary保存文件在服务器上,这是直接采用tensorboard会有一些小问题.直接用t ...
 - Postman请求运行顺序及Workflow
			
作为一款接口调试利器, Postman的更新迭代速度很快, 不断加入了很多新的功能.使的api设计,测试,监控, Mock,以及团队协作更加方便. 修改执行顺序 在遇到有接口依赖的情况, 我们往往需要 ...
 - UVA 12501 Bulky process of bulk reduction ——(线段树成段更新)
			
和普通的线段树不同的是,查询x~y的话,给出的答案是第一个值的一倍加上第二个值的两倍一直到第n个值的n倍. 思路的话,就是关于query和pushup的方法.用一个新的变量sum记录一下这个区间里面按 ...
 - DbFunctions  作为 LINQ to Entities 查询的一部分使用时,此方法调用规范 CreateDateTime EDM 函数以创建新的 DateTime 对象。
			
DbFunctions.CreateDateTime CreateDateTime(year, month,day,hour,minute,second)
 - Windows环境安装MySQL8.0.11
			
网络开发数据库是必不可少的.曾经安装个Mysql,但是忘了.再次安装还是得百度.那还不如自己写篇博客记录一下呢,以后再忘记就看自己的博客好 Mysql官网安装地址(windows环境): https: ...