[TOC]
# Mobx
http://cn.mobx.js.org
https://github.com/mobxjs
哲學思想:
>當應用狀態更新時,所有依賴于這些應用狀態的監聽者(包括 UI 、服務端數據同步函數等),都應該自動得到細粒度地更新。

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