mobX簡介
在 react 項目中,可以使用 context、redux 來做狀態管理,同樣也可以使用 mobx 來做狀態管理。從操作方面來講,mobx 比 redux 的操作更簡單。
mobx 的核心概念有 observable
、computed
、reactions
和 actions
,掌握這幾個概念,就可以在項目中游刃有餘地使用 mobx了。
本篇文章主要講解 mobx 中的幾個核心概念,如果想了解在react項目中如何使用mobx,可以查看另一篇文章,在React項目中使用mobx實現簡單的todolist功能
1. 安裝
在終端中執行yarn add mobx -S
,安裝 mobx 到生產環境中。
2. observable
使用observable
來定義一個可觀察的狀態
,類似於redux 中 store 裏的數據。可以採用聲明式定義,也可以使用裝飾器的寫法。
要聲明對象
或者數組
類型的變量可以直接在 observable()
中傳入對應的數據,如果是聲明 js 基礎類型的變量,需要使用 observable.box()
。
import {observable} from 'mobx';
//map類型:
const map=observable.map
map.set('a',100)
map.get('a')
//對象類型:
const obj=observable({a:3,b:4})
//數組類型:
const arr=observable(['a','b','c'])
//定義js基礎類型,要使用observable.box():
const num=observable.box(10) //number類型
num.set(2) //使用set()修改
console.log(num.get()) //2 使用get()讀取
const str=observable.box('hello')//string類型
str.set('hahha') //使用set()修改
console.log(str.get()) //hahha 使用get()讀取
裝飾器寫法,如果使用 @observable
裝飾器,要確保在你的編譯器(babel 或者 typescript)中裝飾器是啓用的。
//裝飾器的寫法:
class Store{
@observable arr=[];
@observable str='hahaha';
@observable num=3;
@observable bool=true;
}
3 computed
- 使用
computed
可以根據現有的狀態或其它計算值衍生出新的值,當數據有變化時,會自動計算出新的值。 computed()
是一個函數,當調用該函數的時候會執行。- 同樣也可以使用裝飾器
@computed
的語法來寫。
import {computed} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10
//只要str 和 num有變化 ,就可以返回新的result
const result=computed(()=>{
return sotre.str+store.num;
})
//裝飾器的寫法
@computed
get result() {
return this.str + this.num;
}
}
4. reactions
computed
計算值
是自動響應狀態變化的值。 reactions
反應
是自動響應狀態變化的副作用。它用來監聽observable 的變化,執行對應的操作。
4.1 autorun
autorun
的特點是它默認會自動執行一次
,只要autorun裏相關的任何數據有變化 ,autorun都會執行。
import {autorun} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10;
}
const store = new Store()
autorun(() => {
console.log(store.str+store.num); //hello10
})
注意:不要把 computed 和 autorun 搞混。它們都是響應式調用的表達式,但是,如果你想響應式的產生
一個可以被其它 observer 使用的值
,請使用 @computed
,如果你不想產生一個新值,而想要達到一個效果,請使用 autorun。
4.2 when
when
接收兩個函數參數
,第一個函數返回一個boolean
值,只有當第一個函數返回值爲ture
時,纔會執行第二個函數。
import {when} from 'mobx'
class Store {
@observable bool = true
@observable num = 10
}
const store = new Store()
when(()=>store.bool,()=>{
console.log(store.num) //10
})
4.3 reaction
- reaction 默認不會自動執行。
- 它可以說是
autorun
的變種
,接收兩個函數作爲參數。 - 第一個函數必須有返回值,只有當第一個函數
返回值有變化後
,纔會執行
第二個函數。 - 第一個函數每次返回新的值,都會執行第二個函數,也就是說修改
幾次
數據,就會執行幾次
第二個函數。 - 第二個函數中的的第一個參數爲第一個函數返回的數據。
import {reaction} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10
}
const store = new Store()
reaction(()=>{
return [store.str,store.num]
},(data)=>{ //data爲第一個參數中返回的數據
console.log(data) //hello 10
})
5. action
- 使用
action
對observable
進行修改,直接在修改數據的方法前面加@action
裝飾器就可以。 runInAction()
是進行異步操作時,它其實是action() 的語法糖。@action.bound
解決this指向的問題,用來自動地將動作綁定到目標對象。
注意: action.bound 不要和箭頭函數一起使用;箭頭函數已經是綁定過的並且不能重新綁定。
import {action} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10
@action //對數據進行修改
bar() {
this.str = "hello world"
this.num = 100
}
@action.bound //解決this指向的問題
increment() {
this.num++ // 'this' 永遠都是正確的
}
//異步操作寫在runInAction()中
runInAction(()=>{
this.num = 100
})
更多的API介紹可以查看mobX官網:https://cn.mobx.js.org