閱讀時間:大概在 3 分鐘左右javascript
本文章旨在介紹Mobx,不對其餘狀態管理工具進行比較。html
Redux 開啓了前端狀態管理大門,可是對於一些比較小的應用,使用 Redux 反而增長了開發複雜度,這時候,我會選擇使用 Mobx 來進行狀態管理。前端
Mobx是一個經過函數響應式編程,讓狀態管理更加簡單和容易拓展的庫。java
它遵循一個最簡單的原則:react
Anything that can be derived from the application state, should be derived. Automatically.git
(全部可以從應用狀態得到的東西,都應該自動地被得到)github
他的原理很是簡潔:編程
Mobx 爲 JavaScript 自己已有的幾種數據結構都添加了可觀察的功能,也可使用ES6的新特性,經過裝飾器來添加這些功能。數組
可觀察的對象:網絡
import {observable, autorun, action} from "mobx";
var person = observable({
// 可觀察的屬性
name: "John",
age: 42,
showAge: false,
// 計算後的屬性
get labelText() {
return this.showAge ? `${this.name} (age: ${this.age})` : this.name;
},
// action
setAge: action(function(age) {
this.age = age;
})
});
// autorun 函數是來運行狀態後更新後引起的 reaction
autorun(() => console.log(person.labelText));
person.name = "Dave";
// 輸出: 'Dave'
複製代碼
可觀察的數組:
import {observable, autorun} from "mobx";
var todos = observable([
{ title: "Spoil tea", completed: true },
{ title: "Make coffee", completed: false }
]);
autorun(() => {
console.log("Remaining:", todos
.filter(todo => !todo.completed)
.map(todo => todo.title)
.join(", ")
);
});
todos[0].completed = false;
// 輸出: 'Remaining: Spoil tea, Make coffee'
todos[2] = { title: 'Take a nap', completed: false };
// 輸出: 'Remaining: Spoil tea, Make coffee, Take a nap'
todos.shift();
// 輸出: 'Remaining: Make coffee, Take a nap'
複製代碼
可觀察的Map:
import {observable} from "mobx";
const map = observable.map();
map.set("a", 100);
console.log(map.get("a"))
// 輸出: 100
map.observe(({name, newValue}) => console.log(name, "->", newValue))
map.set("b",100)
// 輸出: b -> 100
複製代碼
原生的值和引用:
import {observable} from "mobx";
const cityName = observable("Vienna");
console.log(cityName.get());
// 輸出 'Vienna'
cityName.observe(function(change) {
console.log(change.oldValue, "->", change.newValue);
});
cityName.set("Amsterdam");
// 輸出 'Vienna -> Amsterdam'
複製代碼
狀態管理中有一個重要的概念,狀態應該以一種方式來更新。在Mobx之中,並不須要觸發事件、調用分發函數或者相似的動做,狀態的基本相應派發由 Mobx 自己來負責。
可是讓Mobx全盤接管顯然限制了可拓展性和可用性,因此Mobx提供了Actions來使用。Actions應該永遠只對修改狀態的函數使用動做。建議對任何修改 observables 或具備反作用的函數使用 (@)action
。 結合開發者工具的話,動做還能提供很是有用的調試信息。
Reactions 和計算值很像,但它不是產生一個新的值,而是會產生一些反作用,好比打印到控制檯、網絡請求、遞增地更新 React 組件樹以修補DOM、等等。 簡而言之,reactions 在 響應式編程和命令式編程之間創建溝通的橋樑。
談了那麼多概念那麼怎麼在 React 裏面使用呢。
observer
函數/裝飾器能夠用來將 React 組件轉變成響應式組件。 它用 mobx.autorun
包裝了組件的 render 函數以確保任何組件渲染中使用的數據變化時均可以強制刷新組件。 observer
是由單獨的 mobx-react
包提供的。
import {observer} from "mobx-react";
var timerData = observable({
secondsPassed: 0
});
setInterval(() => {
timerData.secondsPassed++;
}, 1000);
@observer class Timer extends React.Component {
render() {
return (<span>Seconds passed: { this.props.timerData.secondsPassed } </span> )
}
};
React.render(<Timer timerData={timerData} />, document.body);
複製代碼
mobx 使用的時候,確保讓observer滲透到最深處的組件,由於狀態是向下傳遞的,若是原子組件沒有加入Mobx的觀察,那麼就可能就沒有效果。
拓展閱讀