- Published on
MobX
- Authors
- Name
- 不作声
- GitHub
- Github @buzuosheng
MobX三大要点
1、定义状态并使其可观察
2、创建视图以响应状态的变化
3、更改状态
概念与原则
1、State状态
状态是驱动应用的数据。通常像有待办事项列表这样的领域特定状态,还有像当前已选元素的视图状态。状态就像是有数据的Excel表。
2、Derivation衍生
任何源自状态并且不会再有任何进一步的相互作用的东西就是衍生。衍生以多种形式存在:
- 用户界面
- 衍生数据,比如剩下的待办事项的数量。
- 后端集成,
MobX区分了两种类型的衍生:
- Computed values(计算值)-它们是永远使用纯函数从当前可观察状态中衍生出的值。
- Reactions(反应)-Reactions是当前状态
3、Actions
动作是任意一段可以改变状态的代码。用户事件、后端数据发送、预定事件等等。动作类似于用户在excel单元格中插入一个新的值。
4、原则
MobX支持单向数据流,也就是动作改变状态,而状态的改变会更新所有受影响的视图。
当状态改变时,所有衍生都会进行原子级的自动更新。因此永远不可能观察到中间值。
所有衍生默认都是同步更新,这意味着动作可以在改变状态之后直接可以安全的检查计算值。
计算值 是延迟更新的。任何不在使用状态的计算值将不会更新,直到需要它进行副作用(I / O)操作时。 如果视图不再使用,那么它会自动被垃圾回收。
所有的计算值都应该是纯净的。它们不应该用来改变状态。
MobX工作流程
快速上手
1、observable
observable是一种让数据的变化可以被观察的方法,底层是通过把该属性转化成getter/setter。
Observable 值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射。
observable使用:
- 对于JS基本数据类型(Number/String/Boolean),使用observable.box()方法设置;
- 对于数组、对象类型,使用observable()方法设置;
- 对于映射类型,使用observable.map()方法设置;
- 装饰器@observable可以直接定义这些类型。
2、响应observable
2.1、(@)computed
计算值(computed values)是可以根据现有的状态或其它计算值衍生出的值。计算值还是高度优化过的,它们有助于使实际可修改的状态尽可能的小。
计算值是相关状态变化时自动更新的值,可以将多个可观察数据合并成一个可观察数据,且只有在被使用时才会自动更新。
computed使用:
- 使用@computed声明式创建;
- 使用decorate引入;
- 使用observable.object创建。
2.2、autorun
autorun
就是自动运行的意思。当使用autorun
时,所提供的函数总是立即被触发一次,然后每次它的依赖关系发生改变时会再次触发。
computed和autorun对比:
**相同点:**都是响应式调用的表达式。
不同点:
- @computed用于响应式的产生一个可以被其他observable使用的值,autorun不产生新的值,而是产生一个效果。
- @computed中,如果一个计算值不再被观察了,MobX可以自动地将其垃圾回收;而autorun必须手动清理。
2.3、when
when(predicate: () => boolean, effect?: () => void, options?)
when
接收两个函数参数,第一个函数preidcate
根据可观察数据返回一个布尔值。如果返回true,effect
就会被执行,然后autorun自动运行函数就会被清理。
如果没有提供effect
函数,when
会返回一个Promise
。可以与async/await
完美结合。
2.4、reaction
reaction(() => data, (data, reaction) => { sideEffect }, options?)
reaction
接收两个函数参数,返回一个清理函数。
第一个函数参数引用可观察数据,返回一个可观察数据data,作为第二个函数的参数。
创建reaction函数时,不会直接运行,只有当数据表达式首次返回一个新值后才会运行。在执行reaction函数时访问的任何observable都不会被追踪。
第二个函数参数接收两个参数(副作用函数),一个参数是之前返回的data,另一是reaction,用于清理reaction。
3、修改observable
3.1、(@)action
action
是用来修改状态的东西。应该永远只对修改状态的函数使用动作。 只执行查找,过滤器等函数不应该被标记为动作,以允许 MobX 跟踪它们的调用。
(@)action.bound
可以用来自动地将动作绑定到目标对象。与action不同的是,(@)action.bound
不需要一个name参数,名称将始终基于动作绑定的属性。
action可以分批操作状态,一次动作中包含多次修改可观察状态。在动作完成之后,会做一次性的重新计算和反应。
3.2、async actions
runInAction
是一个简单的工具函数,接收代码块在异步动作中执行。runInAction(f)
实际上是 action(f)()
的语法糖。
总结
- 使用
(@)observable
设置可观察数据 - 使用
(@)computed/autorun/when/reaction
对可观察数据做出响应computed
可以将多个可观察数据组合成一个可观察数据;autorun
自动追踪可观察数据,在数据发生改变时自动执行;when
设置自动触发变化的实际,是autorun
的一个变种情况;reaction
分离可观察数据,以副作用的方式对autorun
进行改进
- 使用
(@)action
修改可观察数据,且有编写异步代码的几种方式Promises
runInAction
async/await
- flows
MobX与Redux相比:
Redux的编程范式是函数式的;而MobX是面向对象的。
Redux的数据理想上是immutable的,每次都返回一个新的数据,因此Redux是支持数据回溯的;而MobX始终都是一份引用。
Redux使用dispatch进行广播,通过Provider和connect来对比前后差别控制更新粒度;MobX的observable控制的更加精细。