-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Mobx
入门了解
通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。
- 任何源自应用状态的东西都应该自动地获得,包括UI、数据序列化、服务器通讯。
- MobX 会对在执行跟踪函数期间读取的任何现有的可观察属性做出反应。
- 观察者模式包含两个角色:一个Observable和一个或者多个Observers。Observable发送事件,而Observer订阅和接收这些事件。
- 响应式编程是使用异步数据流进行编程
React 和 MobX 是一对强力组合。React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而MobX提供机制来存储和更新应用状态供 React 使用。
React 提供了优化UI渲染的机制, 这种机制就是通过使用虚拟DOM来减少昂贵的DOM变化的数量。
MobX 提供了优化应用状态与 React 组件同步的机制,这种机制就是使用响应式虚拟依赖状态图表,它只有在真正需要的时候才更新并且永远保持是最新的。
MobX 要点
- 定义状态并使其可观察
- 创建视图以响应状态的变化
- 更改状态
核心概念
Observable state(可观察的状态)
为现有的数据结构(如对象,数组和类实例)添加了可观察的功能;
通过使用 @observable 装饰器(ES.Next)来给你的类属性添加注解就可以简单地完成这一切。
import { observable } from "mobx";
class Todo {
id = Math.random();
@observable title = "";
@observable finished = false;
}
Computed values(计算值)
定义在相关数据发生变化时自动更新的值。
通过@computed 装饰器或者利用 (extend)Observable 时调用 的getter / setter 函数来进行使用。
class TodoList {
@observable todos = [];
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
}
}
Reactions(反应)
Reactions 和计算值很像,但它不是产生一个新的值,而是会产生一些副作用,比如打印到控制台、网络请求、递增地更新 React 组件树以修补DOM、等等。 简而言之,reactions 在 响应式编程和命令式编程之间建立沟通的桥梁。
React 组件
React 下,可以把(无状态函数)组件变成响应式组件,方法是在组件上添加 observer 函数/ 装饰器. observer由 mobx-react 包提供的。
observer 会将 React (函数)组件转换为它们需要渲染的数据的衍生。
自定义 reactions
使用autorun、reaction 和 when 函数即可简单的创建自定义 reactions,以满足你的具体场景。
如:unfinishedTodoCount 的数量发生变化时,下面的 autorun 会打印日志消息:
autorun(() => {
console.log("Tasks left: " + todos.unfinishedTodoCount)
})
Actions(动作)
装饰符语法的例子
需要设置和编译,目前只有 Babel/Typescript 编译器支持
// 装饰符语法
import { observable, computed, action } from "mobx";
class Timer {
@observable start = Date.now();
@observable current = Date.now();
@computed
get elapsedTime() {
return this.current - this.start + "milliseconds";
}
@action
tick() {
this.current = Date.now();
}
}
装饰器语法的优劣性:
优势:
- 样板文件最小化,声明式代码。
- 易于使用和阅读。大多数 MobX 用户都在使用。
劣势:
- ES.next 2阶段特性。
- 需要设置和编译,目前只有 Babel/Typescript 编译器支持。
使用装饰器的两种方式
- 开启编译器的实验性装饰器语法
- 不启用装饰器语法,而是利用 MobX 内置的工具 decorate 来对类和对象进行装饰。
上代码同:
import { observable, computed, action, decorate } from "mobx";
class Timer {
start = Date.now();
current = Date.now();
get elapsedTime() {
return this.current - this.start + "milliseconds";
}
tick() {
this.current = Date.now()
}
}
decorate(Timer, {
start: observable,
current: observable,
elapsedTime: computed,
tick: action
})
mobx-react 中的observer 函数既是装饰器也是函数:
@observer
class Timer extends React.Component {
/* ... */
}
const Timer = observer(class Timer extends React.Component {
/* ... */
})
const Timer = observer((props) => (
/* 渲染 */
))
启用装饰符语法
- TypeScript: tsconfig.json 中启用编译器选项 "experimentalDecorators": true ;
- Babel:
- 使用 babel-preset-mobx
- 使用 mobx preset,这种方式更方便,其中包含了装饰器及其他几个经常与 mobx 一起使用的插件:
npm install --save-dev babel-preset-mobx
.babelrc:
{
"presets": ["mobx"]
}
- 要启用装饰器的支持而不使用 mobx preset
npm i --save-dev babel-plugin-transform-decorators-legacy
{
"presets": ["es2015", "stage-1"],
"plugins": ["transform-decorators-legacy"]
}
MobX 社区并没有正式支持以下模式:
- 重新定义继承树中的装饰类成员
- 装饰静态类成员
- 将 MobX 提供的装饰器与其他装饰器组合
- 热更新 (HMR) / React-hot-loader 可能不能正常运行
