Mobx —— React狀態管理另外一條路

閱讀時間:大概在 3 分鐘左右javascript

本文章旨在介紹Mobx,不對其餘狀態管理工具進行比較。html

Redux 開啓了前端狀態管理大門,可是對於一些比較小的應用,使用 Redux 反而增長了開發複雜度,這時候,我會選擇使用 Mobx 來進行狀態管理。前端

Mobx 是什麼

Mobx是一個經過函數響應式編程,讓狀態管理更加簡單和容易拓展的庫。java

它遵循一個最簡單的原則:react

Anything that can be derived from the application state, should be derived. Automatically.git

(全部可以從應用狀態得到的東西,都應該自動地被得到)github

他的原理很是簡潔:編程

mobx原理圖

  • Actions 是惟一容許修改state並且有其餘反作用的函數
  • State 是一組可觀察的狀態,並且不該該包含冗餘的數據(例如不會被更新的狀態)
  • Computed Value 是一些純函數,返回經過 state 能夠推導出的值
  • Reactions 相似於 Computed Value,可是它容許反作用的產生(如更新 UI 狀態)

核心概念

Observable state

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'
複製代碼

Actions

狀態管理中有一個重要的概念,狀態應該以一種方式來更新。在Mobx之中,並不須要觸發事件、調用分發函數或者相似的動做,狀態的基本相應派發由 Mobx 自己來負責。

可是讓Mobx全盤接管顯然限制了可拓展性和可用性,因此Mobx提供了Actions來使用。Actions應該永遠只對修改狀態的函數使用動做。建議對任何修改 observables 或具備反作用的函數使用 (@)action 。 結合開發者工具的話,動做還能提供很是有用的調試信息。

Reactions

Reactions 和計算值很像,但它不是產生一個新的值,而是會產生一些反作用,好比打印到控制檯、網絡請求、遞增地更新 React 組件樹以修補DOM、等等。 簡而言之,reactions 在 響應式編程和命令式編程之間創建溝通的橋樑。

在 React 裏使用 Mobx

談了那麼多概念那麼怎麼在 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的觀察,那麼就可能就沒有效果。

拓展閱讀

官方文檔

十分鐘交互式的 MobX + React 教程

訪談: 狀態管理很容易 - React Amsterdam 2016 開發者大會 (幻燈片)

相關文章
相關標籤/搜索