# Mobx 基础
# Basic 基础
什么是 Mobx:简单、可扩展的状态管理解决方案
# Core 核心思想
背景
State is the heart of each application and there is no quicker way to create buggy, unmanageable applications than by producing an inconsistent state or state that is out-of-sync with local variables that linger around. Hence many state management solutions try to restrict the ways in which you can modify state, for example by making state immutable. But this introduces new problems; data needs to be normalized, referential integrity can no longer be guaranteed and it becomes next to impossible to use powerful concepts like prototypes.
状态是每个应用程序的核心,没有比创建不一致的状态或与徘徊不定的局部变量不同步的状态更快的方法来创建有缺陷的,难以管理的应用程序。因此,许多状态管理解决方案试图限制修改状态的方式,例如通过使状态不可变。但这带来了新的问题。数据需要规范化,无法再确保参照完整性,因此使用功能强大的概念(例如原型)几乎变得不可能。
Mobx
MobX makes state management simple again by addressing the root issue: it makes it impossible to produce an inconsistent state. The strategy to achieve that is simple: Make sure that everything that can be derived from the application state, will be derived. Automatically
MobX通过解决根本问题而使状态管理再次变得简单:它使得不可能产生不一致的状态。实现这一目标的策略很简单:确保所有可以从应用程序状态派生的内容都将被派生。自动地
任何源自应用状态的东西都应该自动地获得
参考:https://cn.mobx.js.org/#%E5%85%A5%E9%97%A8
# 设计
MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程
(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展
mobx 原理:
# 概念
- Actions
- Observable state
- Computed values
- Reactions
- Derivations(衍生)
Actions 行为 更改和监听状态,分为隐式和显示更改
隐式:
this.unit = unit
显示
@action setUnit(unit){
this.unit = unit
}
MobX 对于如何处理用户事件是完全开明的。状态应该以某种方式来更新,但是Mobx并不限制以特定的方式。可以用:
- 可以用类似 Flux 的方式完成
- 或者使用 RxJS 来处理事件
- 或者用最直观、最简单的原生方式来处理事件
当状态更新后,MobX 会以一种高效且无障碍的方式处理好剩下的事情。从技术上层面来讲,并不需要触发事件、调用分派程序或者类似的工作。归根究底 React 组件只是状态的华丽展示,而状态的衍生由 MobX 来管理。
store.todos.push(
new Todo("Get Coffee"),
new Todo("Write simpler code")
);
store.todos[0].finished = true;
尽管如此,MobX 还是提供了 actions 这个可选的内置概念。使用 actions 是有优势的: 它们可以帮助你把代码组织的更好,还能在状态何时何地应该被修改这个问题上帮助你做出明智的决定
中文文档:Actions (opens new window)
Observable state 可观察状态 MobX 为现有的数据结构(如对象,数组和类实例)添加了可观察的功能
import { observable } from "mobx";
class Todo {
id = Math.random();
@observable title = "";
@observable finished = false;
}
使用 observable 很像把对象的属性变成excel的单元格。 但和单元格不同的是,这些值不只是原始值,还可以是引用值,比如对象和数组
状态 是驱动应用的数据
Computed values 计算值 使用 MobX, 你可以定义在相关数据发生变化时自动更新的值。 通过@computed 装饰器或者利用 (extend)Observable 时调用 的getter / setter 函数来进行使用
和电子表格中的值非常类似,计算值不允许有副作用(例如改变状态或者网络请求),应该是一个纯函数
计算值从状态中得出一个值,如果不需要,将自动挂起。
Reactions 反应 为了使计算值能够得到一个响应,必须消费它们。我们叫做反应。反应不产生新的值,但它们会产生副作用。
Reactions 和计算值
很像,但它不是产生一个新的值,而是会产生一些副作用,比如打印到控制台、网络请求、递增地更新 React 组件树以修补DOM、等等。 简而言之,reactions 在 响应式编程和命令式编程之间建立沟通的桥梁
eg: observer observer 装饰器的副作用就是决定是否推送一个 DOM 渲染
Derivations 衍生 任何 源自状态并且不会再有任何进一步的相互作用的东西就是衍生。 衍生以多种形式存在:
- 用户界面
- 衍生数据,比如剩下的待办事项的数量
- 后端集成,比如把变化发送到服务器端
MobX 区分了两种类型的衍生:
- Computed values(计算值): 它们是永远可以使用纯函数(pure function)从当前可观察状态中衍生出的值。
- Reactions(反应): Reactions 是当状态改变时需要自动发生的副作用。需要有一个桥梁来连接命令式编程(imperative programming)和响应式编程(reactive programming)。或者说得更明确一些,它们最终都需要实现I / O 操作
# Concepts 原则
MobX 支持单向数据流,也就是动作改变状态,而状态的改变会更新所有受影响的视图。
Action --> State --> View
当状态改变时,所有衍生都会进行原子级的自动更新
。因此永远不可能观察到中间值。
所有衍生默认都是同步更新
。这意味着例如动作可以在改变状态之后直接可以安全地检查计算值。
计算值是延迟更新
的。任何不在使用状态的计算值将不会更新,直到需要它进行副作用(I/O)操作时。 如果视图不再使用,那么它会自动被垃圾回收。
所有的计算值都应该是纯净的。它们不应该用来改变状态
# Mobx And React
React 和 MobX 是一对强力组合。React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而MobX提供机制来存储和更新应用状态供 React 使用。
对于应用开发中的常见问题,React 和 MobX 都提供了最优和独特的解决方案。React 提供了优化UI渲染的机制, 这种机制就是通过使用虚拟DOM来减少昂贵的DOM变化的数量。MobX 提供了优化应用状态与 React 组件同步的机制,这种机制就是使用响应式虚拟依赖状态图表,它只有在真正需要的时候才更新并且永远保持是最新的。
# 使用
- 定义状态并使其可观察
- 创建视图以响应状态的变化
← Redux Links Mobx-API →