初識MobX

http://blog.poetries.top/2018/08/31/acq-mobx/

關(guān)注公眾號獲取更多資訊

一抒线、認識MobX

打印mobx讨越,看看mobx中有什么

mobx

MobX的整個流程

image

MobX 和 Redux 的比較

  • Redux 是單一數(shù)據(jù)源,而 MobX 往往是多個 storeMobX 可以根據(jù)應(yīng)用的 UI、數(shù)據(jù)或業(yè)務(wù)邏輯來組織 store,具體如何進行需要你自己進行權(quán)衡
  • Redux store 使用普通的 JavaScript 對象結(jié)構(gòu)剩燥,MobX 將常規(guī) JavaScript 對象包裹,賦予 observable 的能力立倍,通過隱式訂閱灭红,自動跟蹤 observable 的變化。MobX 是觀察引用的口注,在跟蹤函數(shù)中(例如:computed value变擒、reactions等等),任何被引用的 observable 的屬性都會被記錄疆导,一旦引用改變赁项,MobX 將作出反應(yīng)葛躏。注意,不在跟蹤函數(shù)中的屬性將不會被跟蹤悠菜,在異步中訪問的屬性也不會被跟蹤
  • Reduxstate 是只讀的舰攒,只能通過將之前的 state 與觸發(fā)的 action 結(jié)合,產(chǎn)生新的 state悔醋,因此是純凈的(pure)摩窃。而 MobXstate 即可讀又可寫,action 是非必須的芬骄,可以直接賦值改變猾愿,因此是不純凈的(Impure)
  • Redux 需要你去規(guī)范化你的 stateImmutable 數(shù)據(jù)使 Reducer 在更新時需要將狀態(tài)樹的祖先數(shù)據(jù)進行復(fù)制和更新账阻,新的對象會導致與之 connect的所有 UI 組件都重復(fù)渲染蒂秘。因此Redux state 不建議進行深層嵌套,或者需要我們在組件中用 shouldComponentUpdate 優(yōu)化淘太。而 MobX 只自動更新你所關(guān)心的姻僧,不必擔心嵌套帶來的重渲染問題

redux 管理的是 (STORE -> VIEW -> ACTION) 的整個閉環(huán),而 mobx 只關(guān)心 STORE -> VIEW 的部分

優(yōu)點

  • 基于運行時的數(shù)據(jù)訂閱 mobx 的數(shù)據(jù)依賴始終保持了最小蒲牧,而且還是基于運行時撇贺。而如果用 redux,可能一不小心就多訂閱或者少訂閱了數(shù)據(jù)冰抢。所以為了達到高性能松嘶,我們需要借助 PureRenderMixin 以及 reselectselector 做緩存
  • 通過 OOP 的方式組織領(lǐng)域模型 (domain model) OOP 的方式在某些場景下會比較方便,尤其是容易抽取 domain model 的時候挎扰。進而由于 mobx 支持引用的方式引用數(shù)據(jù)翠订,所以可以非常容易得形成模型圖 (model graph ),這樣可以更好地理解我們的應(yīng)用遵倦。
  • 修改數(shù)據(jù)方便自然 mobx 是基于原生的 JavaScript 對象蕴轨、數(shù)組和 Class實現(xiàn)的。所以修改數(shù)據(jù)不需要額外語法成本骇吭,也不需要始終返回一個新的數(shù)據(jù),而是直接操作數(shù)據(jù)

缺點

  • 缺最佳實踐和社區(qū) mobx 比較新歧寺,遇到的問題可能社區(qū)都沒有遇到過燥狰。并且,mobx 并沒有很好的擴展/插件機制
  • 隨意修改 store 我們都知道 redux 里唯一可以改數(shù)據(jù)的地方是 reducer斜筐,這樣可以保證應(yīng)用的安全穩(wěn)定龙致;而 mobx 可以隨意修改數(shù)據(jù),觸發(fā)更新顷链,給人一種不安全的感覺
    • 最新的mobx 2.2 加入了 action 的支持目代。并且在開啟 strict mode 之后,就只有 action 可以對數(shù)據(jù)進行修改,限制數(shù)據(jù)的修改入口榛了≡谘龋可以解決這個問題
  • 邏輯層的限制
    • 如果更新邏輯不能很好地封裝在 domain class 里,用 redux 會更合適霜大。另外构哺,mobx缺類 redux-saga 的庫,業(yè)務(wù)邏輯的整合不知道放哪合適

二战坤、核心API

image.png

2.1 @observable

Observable 值可以是JS基本數(shù)據(jù)類型曙强、引用類型、普通對象途茫、類實例碟嘴、數(shù)組和映射。其修飾的state會暴露出來供觀察者使用

// Observable 值可以是JS基本數(shù)據(jù)類型囊卜、引用類型娜扇、普通對象、類實例边败、數(shù)組和映射
@observable title = 'this is about page'
@observable num = 0

// 計算值(computed values)是可以根據(jù)現(xiàn)有的狀態(tài)或其它計算值衍生出的值
@computed get getUserInfo(){
   return `我是computed經(jīng)過計算的getter,currenct num:${this.num}`
}
// 注意:當你使用裝飾器模式時袱衷,@action 中的 this 沒有綁定在當前這個實例上,要用過 @action.bound 來綁定 使得 this 綁定在實例對象上
@action.bound add(){
    this.num ++
}
@action.bound reduce(){
    this.num --
}

2.2 observer

可以用作包裹 React 組件的高階組件笑窜。 在組件的 render 函數(shù)中的任何已使用的 observable 發(fā)生變化時致燥,組件都會自動重新渲染。 注意 observer 是由 "mobx-react" 包提供的排截,而不是 mobx 本身

  • @Observer 是一個注解嫌蚤,本質(zhì)上是用 mobx.autorun 包裝了組件的 render 函數(shù)以確保任何組件渲染中使用的數(shù)據(jù)變化時都可以強制刷新組件

2.3 @computed

  • 計算值(computed values)是可以根據(jù)現(xiàn)有的狀態(tài)或其它計算值衍生出的值
  • 用于獲取由基礎(chǔ) state衍生出來的值。如果基礎(chǔ)值沒有變断傲,獲取衍生值時就會走緩存脱吱,這樣就不會引起虛擬 DOM 的重新渲染
  • getter:獲得計算得到的新state并返回。
  • setter: 不能用來直接改變計算屬性的值认罩,但是它們可以用來作“逆向”衍生箱蝠。

通過 @computed + getter函數(shù)來定義衍生值

class Foo {
    @observable length = 2;
    @computed get squared() {
        return this.length * this.length;
    }
    set squared(value) { // 這是一個自動的動作,不需要注解
        this.length = Math.sqrt(value);
    }
}

2.4 @actions

  • 只有在 actions 中垦垂,才可以修改 Mobxstate 的值
  • 注意:當你使用裝飾器模式時宦搬,@action 中的 this 沒有綁定在當前這個實例上,要用過 @action.bound 來綁定 使得 this 綁定在實例對象上
  • 通過引入 mobx 定義的嚴格模式劫拗,強制使用 action 來修改狀態(tài)
import {configure} from 'mobx';

configure({ enforceActions: 'always' }) // 開啟嚴格模式
@action.bound add(){
    this.num ++
}
@action.bound reduce(){
    this.num --
}

2.5 autorun

  • 當可觀察對象中保存的值發(fā)生變化時间校,可以在mobx.autorun中被觀察到。observable 的值初始化或改變時页慷,自動運行
  • 如果你想響應(yīng)式的產(chǎn)生一個可以被其它 observer 使用的值憔足,請使用 @computed胁附,如果你不想產(chǎn)生一個新值,而想要達到一個效果滓彰,請使用 autorun捉蚤。 舉例來說猴贰,效果是像打印日志鸠项、發(fā)起網(wǎng)絡(luò)請求等這樣命令式的副作用
import {
  observable,
  computed,
  action,
 autorun
} from 'mobx'

 class AppState {
  constructor({ count, name } = { count: 0, name: 'Jokcy' }) {
    this.count = count
    this.name = name
  }
  @observable count
  @observable name
  @computed get msg() {
    return `${this.name} say count is ${this.count}`
  }
  @action add() {
    this.count += 1
  }
  @action changeName(name) {
    this.name = name
  }
  toJson() {
    return {
      count: this.count,
      name: this.name,
    }
  }
}

const appState = new AppState()

// 一旦appState有更新執(zhí)行方法
autorun(()=>{
    console.log(appState.msg)
})

export default AppState

2.6 reactions

Reactions和計算值很像婚被,但它不是產(chǎn)生一個新的值,而是會產(chǎn)生一些副作用洗做,比如打印到控制臺弓叛、網(wǎng)絡(luò)請求、遞增地更新 React組件樹以修補DOM诚纸、等等撰筷。 簡而言之,reactions 在 響應(yīng)式編程和命令式編程之間建立溝通的橋梁

2.7 Flow

用法: flow(function* (args) { })

  • flow() 接收 generator 函數(shù)作為它唯一的輸入
import { configure } from 'mobx';

// 不允許在動作外部修改狀態(tài)
configure({ enforceActions: true });

class Store {
    @observable githubProjects = [];
    @observable state = "pending"; // "pending" / "done" / "error"


    fetchProjects = flow(function* fetchProjects() { // <- 注意*號畦徘,這是生成器函數(shù)毕籽!
        this.githubProjects = [];
        this.state = "pending";
        try {
            const projects = yield fetchGithubProjectsSomehow(); // 用 yield 代替 await
            const filteredProjects = somePreprocessing(projects);

            // 異步代碼自動會被 `action` 包裝
            this.state = "done";
            this.githubProjects = filteredProjects;
        } catch (error) {
            this.state = "error";
        }
    })
}

三、計數(shù)器例子

import React, { Component } from 'react';
import { observer } from 'mobx-react';//結(jié)合react
import { observable, autorun,computed } from 'mobx';

// 定義數(shù)據(jù)store
class Counter {
  @observable number = 0;
  @computed get msg() {
    return 'number:' + this.number
  }
  // 用action改變數(shù)據(jù)井辆,避免混亂
  @action increment(){
    this.number ++
  }
  @action decrement: () => {
    this.number --
  }
}

var store = new Counter()

// 把屬性注入react組件
@observer
class App extends Component {
  render() {
    return (<div>
        { store.msg } <br />
      <button onClick={this.handleInc}> + </button>
      <button onClick={this.handleDec}> - </button>
    </div>);
  }
  handleInc() {
    store.increment();
  }
  handleDec() {
    store.decrement();
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

四关筒、應(yīng)用案例

https://github.com/poetries/react-mobx-template

五、參考

文檔學習 https://cn.mobx.js.org/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杯缺,一起剝皮案震驚了整個濱河市蒸播,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萍肆,老刑警劉巖袍榆,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異塘揣,居然都是意外死亡包雀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門亲铡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來才写,“玉大人,你說我怎么就攤上這事奖蔓±拍Γ” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵锭硼,是天一觀的道長。 經(jīng)常有香客問我蜕劝,道長檀头,這世上最難降的妖魔是什么轰异? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮暑始,結(jié)果婚禮上搭独,老公的妹妹穿的比我還像新娘。我一直安慰自己廊镜,他們只是感情好牙肝,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗤朴,像睡著了一般配椭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雹姊,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天股缸,我揣著相機與錄音,去河邊找鬼吱雏。 笑死敦姻,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的歧杏。 我是一名探鬼主播镰惦,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼犬绒!你這毒婦竟也來了旺入?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤懂更,失蹤者是張志新(化名)和其女友劉穎眨业,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沮协,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡龄捡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了慷暂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聘殖。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖行瑞,靈堂內(nèi)的尸體忽然破棺而出奸腺,到底是詐尸還是另有隱情,我是刑警寧澤血久,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布突照,位于F島的核電站,受9級特大地震影響氧吐,放射性物質(zhì)發(fā)生泄漏讹蘑。R本人自食惡果不足惜末盔,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望座慰。 院中可真熱鬧陨舱,春花似錦、人聲如沸版仔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛮粮。三九已至益缎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝉揍,已是汗流浹背链峭。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留又沾,地道東北人弊仪。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像杖刷,于是被迫代替她去往敵國和親励饵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文首發(fā)于:CSDN「前端開發(fā)者說」公眾號典予。CSDN「前端開發(fā)者說」公眾號(ID:bigfrontend),專注前...
    RachelQG閱讀 4,819評論 2 20
  • 1. 介紹 1.1. 原理 React的render是 狀態(tài) 轉(zhuǎn)化為樹狀結(jié)構(gòu)的渲染組件的方法而MobX提供了一種存...
    三月懶驢閱讀 12,853評論 1 28
  • Mobx解決的問題 傳統(tǒng)React使用的數(shù)據(jù)管理庫為Redux乐严。Redux要解決的問題是統(tǒng)一數(shù)據(jù)流瘤袖,數(shù)據(jù)流完全可控...
    光哥很霸氣閱讀 13,107評論 2 21
  • 66666666666666666
    觀鏡人閱讀 130評論 0 0
  • 資源是一些二進制數(shù)據(jù),它能夠添加到基于窗口的應(yīng)用程序的可執(zhí)行文件中昂验。資源可以是標準的或者自定義的捂敌。資源文件的源文件...
    乘瓠散人閱讀 484評論 0 0