狀態管理庫 MobX 和 react

MobX

  • MobX 是一個簡單、方便擴展、久經考驗的狀態管理解決方案

基本概念

  • MobX 是一個獨立的組件,能夠配合各類框架使用,因爲項目中須要使用 react & MobX。下面來詳細瞭解一下javascript

  • State 是每個應用程序的核心部分,而使用一個不合規範的 State 則是讓你的應用充滿 bug 和失控的不二法門,或者就是局部變量環繞,讓你的 state 失去了同步。有不少框架試圖解決這個問題,好比使用不可變的 state,可是這樣以來又帶來了新的問題,好比數據必須規格化,完整性約束失效等等。java

MobX 功能

  • MobX 讓整個事情又變簡單了:它不容許產生失控的 state。它的理念也很簡單:全部能夠從 state 中派生的事物,都會自動的派生。react

  • demo程序員

class TodoStore {
	todos = [];

	get completedTodosCount() {
    	return this.todos.filter(
			todo => todo.completed === true
		).length;
    }

	report() {
		if (this.todos.length === 0)
			return "<none>";
		return `Next todo: "${this.todos[0].task}". ` + 
			`Progress: ${this.completedTodosCount}/${this.todos.length}`; 
	}

    addTodo(task) {
		this.todos.push({ 
			task: task,
			completed: false,
            assignee: null
		});
	}
}

const todoStore = new TodoStore();
複製代碼

當咱們去建立一個 todoStore,他擁有一個 todos 集合,如今咱們往這個 todoStore 裏添加一些東西,爲了明顯起見,就調用 todoStore.report數組

todoStore.addTodo("read MobX tutorial");
console.log(todoStore.report());
​
todoStore.addTodo("try MobX");
console.log(todoStore.report());
​
todoStore.todos[0].completed = true;
console.log(todoStore.report());
​
todoStore.todos[1].task = "try MobX in own project";
console.log(todoStore.report());
​
todoStore.todos[0].task = "grok MobX tutorial";
console.log(todoStore.report());

複製代碼
  • 太巧了,這就是 MobX 能爲你作的事情。自動執行只在 state 改變的時候觸發,就好像 Excel 中的圖表只在單元格數據改變時更新同樣。爲了達到這個目標,TodoStore 必須成爲可觀測的(observable)才行,讓咱們來改一些代碼。

observable & computed

同時,completedTodosCount 屬性應該被自動派生,使用 @observable 和 @computed 裝飾器來作這些事情:架構

class ObservableTodoStore {
    @observable todos = [];
    @observable pendingRequests = 0;
 
    constructor() {
        mobx.autorun(() => console.log(this.report));
    }
 
    @computed get completedTodosCount() {
    	return this.todos.filter(
			todo => todo.completed === true
		).length;
    }
 
    @computed get report() {
        if (this.todos.length === 0)
            return "<none>";
	return `Next todo: "${this.todos[0].task}". ` + 
	    `Progress: ${this.completedTodosCount}/${this.todos.length}`; 
	}
 
    addTodo(task) {
	this.todos.push({ 
	    task: task,
	    completed: false,
	    assignee: null
	});
    }
}
 
const observableTodoStore = new ObservableTodoStore();

複製代碼
  • 在這個構造器中,咱們使用 autorun 包裹了一個打出 report 的小函數。Autorun 裏的東西首先會運行一次,而後當其中的函數有 observable 的數據發生變化時,會再次運行。 這裏咱們使用了 todos 屬性,每次 todos 變化了咱們就打印出新的東西。
  • 測試一下
observableTodoStore.addTodo("read MobX tutorial");
observableTodoStore.addTodo("try MobX");
observableTodoStore.todos[0].completed = true;
observableTodoStore.todos[1].task = "try MobX in own project";
observableTodoStore.todos[0].task = "grok MobX tutorial";

複製代碼

舉個栗子(sf 的一個問題有感)

  • 對於單個對象,我可使用computed經過計算得到一些屬性,好比
@observable good = {
    number: 2,
    price: 3
}
@computed get totalPrice() {
    return this.good.number * this.good.price;
}

// 數組
@observable goodsList = [{
    number: 2,
    price: 3
},{
    number: 2,
    price: 3
}]
複製代碼
  • 問題?框架

    • 這種狀況我如何經過computed得到數組某個元素的計算屬性呢,仍是隻能在改變number的函數中手動去更改,可是我數組的對象中並無一個totalPrice的屬性,每次把單個good push到goodsList中去還要給good添加一個totalPrice屬性豈不是很麻煩
  • 解決方案函數

    • good 弄成一個單獨的model文件
export default class Good{
  @observable number;
  @observable price;
  constructor(number, price) {
    this.number = number;
    this.price = price;
  }
  
  @computed
  get totalPrice() {
    return this.number * this.price
  }   

}
複製代碼
    • 而後在goodList文件中
    • 這樣就實現了自動計算, 訪問的時候相似 this.props.goodList[0].totalPrice
@action
  addGood(...args) {
    this.todos.push(new Good(...args));
  }
複製代碼
  • 未完待續...

總結

  • 最後總結一些:
  • @observale 修飾器或者 observable 函數讓對象能夠被追蹤;
  • @computed 修飾器創造了自動運算的表達式;
  • autorun 函數讓依靠 observable 的函數自動執行,這個用來寫 log,發請求很不錯;
  • @observer 修飾器讓 React 組建自動起來,它會自動更新,即使是在一個很大的程序裏也會工做的很好;
  • MobX 不是一個狀態容器

不少人把 MobX 看成另一個 Redux,可是它僅僅是一個庫,不是一個什麼架構。上面的例子仍是須要程序員本身去組織邏輯和 store 或者控制器什麼的.測試

引用:

10分鐘極速入門 MobX ui

sf @computed使用

react 官網

相關文章
相關標籤/搜索