[TOC]
# Mobx
http://cn.mobx.js.org
https://github.com/mobxjs
哲学思想:
>当应用状态更新时,所有依赖于这些应用状态的监听者(包括 UI 、服务端数据同步函数等),都应该自动得到细粒度地更新。
![Mobx 哲学思想](https://box.kancloud.cn/3cfdece899293c09410f146c7ae84a0c_1407x483.png)
mobx 推荐使用 ES7 的 decorator 语法,以实现最精炼的表达。通过对 babel 简单的配置,[具体配置](https://cn.mobx.js.org/best/decorators.html) 请参考官方文档。
# 核心概念
* **State**: 业务的最原始状态,通过 observable 方法,可以使这些状态变得可观察。
* **Computed values**: 计算值。**如果你想创建一个基于当前状态的值时,请使用 computed**。
* **Reactions**: 反应,当状态改变时自动发生。
* **Actions**: 动作,用于改变 State 。
* **依赖收集(autoRun)**: MobX 中的数据以来基于**观察者模式**,通过 autoRun 方法添加观察者。
## 基本概念 Observable 和 Reactions
在理解 mobx 之前,我们需要搞清楚 mobx 中的两个基本概念 Observable 和 Reactions :
1. Observable : 需要被监听的应用状态;通过 `@observable` 修饰符可以细粒度地控制一个 Class 的哪个属性需要被监听。
2. Reactions : 应用状态的监听者;当依赖的应用状态发生变化时,能够自动地执行相应的动作。`reaction`、`autorun`、`@observer`都可以生成一个 Reactions。
mobx 通过使用 Observable 和 Reactions 的抽象概念,分别表示**需要被监听的应用状态**和**应用状态的监听者**。
简单示例:
~~~
import {observable, computed, action} from 'mobx';
class userStoreClass {
@observable user = {
name: 'admin',
role: '管理员'
};
count = 0;
@computed get userName(){
return this.user.name;
}
@action changeUser(){
if(this.count % 2 === 1){
this.user = {
name: 'admin',
role: '管理员'
};
}else{
this.user.name = 'guest';
this.user.role = '访客';
this.user.isGuest = 'true';
}
this.count ++;
}
}
const userStore = new userStoreClass();
export default userStore;
// 如果有多个 store,可以使用类似于如下形式:
const stores = {
mainStore, userStore, commonStore
};
ReactDOM.render((
<Provider {...stores}>
<App />
</Provider>
), document.getElementById('container'));
// Timer
import React, {Component} from 'react';
import {inject, observer} from 'mobx-react';
import {observable, action} from "mobx";
import './style.css';
@inject('commonStore')
@observer
export default class Timer extends Component{
constructor(props){
super(props);
this.state = {};
}
// 组件内可观察的局部状态,不使用 setState 也触发 UI 的响应。
@observable secondsPassed = 0;
componentWillMount(){
this.props.commonStore.startTime();
this.timer = setInterval(this.handleChangeSecondsPassed,1000);
}
@action.bound handleChangeSecondsPassed(){
this.secondsPassed ++;
}
// 对于 mobx-react@4+, 当接收新的 props 时并在 setState 调用后会触发此钩子;
componentWillReact() {
console.log("I will re-render, since the user has changed!");
}
render(){
const {time} = this.props.commonStore;
return(
<div className='time_content'>
<div>{time}</div>
<div>Seconds passed:{this.secondsPassed}</div>
</div>
);
}
}
~~~
> [getting-started](https://mobx.js.org/getting-started.html)
# 特点
* 数据流流动不自然,只有用到的数据才会引发绑定,**局部精确更新(细粒度控制)。**
* 没有时间回溯能力,因为数据只有一份引用。
* 基于面向对象。
* 往往是多个 Store。
* 代码侵入性小。
* 简单可扩展。
* 大型项目使用 MobX 会使得代码难以维护。
# 与 redux 的对比
| | redux | mobx |
|---|---| -- |
| 逻辑层完整性 | redux 包括了 store、view、action 的整个数据流 | mobx 只关心 store、view |
| 状态传播 | redux 将组件分为展示型组件和容器型组件,状态只对容器型组件可见,容器型组件需要主动的使用`mapStateToProps`订阅状态 | mobx 对组件没有划分,使用`@observer`后会在运行时动态地订阅状态 |
| 适用性 | redux 要求对整个应用使用单一的状态树,并要求状态的更新必须是 immutable 地,数据流规范,设计严谨。但是其复杂度也比较高,就连最基本的异步操作,也需要中间件( redux-thunk,redux-sage 等)来解决。学习曲线较陡,适合大型项目使用 | mobx 则对应用状态的设计没有特殊要求,极其灵活,异步操作也非常自然,学习曲线平缓,中小型项目中,但缺少最佳实践 |
# mobx-state-tree
https://mobx-state-tree.js.org/intro/philosophy
# 资源
[MobX React Form](https://foxhound87.github.io/mobx-react-form/)
[使用mobx开发高性能react应用](https://foio.github.io/mobx-react/)
http://slides.com/mattruby/practical-forms-with-react-and-mobx