簡潔的MobX與MVP思想

好久以前想寫一篇對Redux的研究,可是網上寫的不少,而MobX相比較Redux更小衆,網上不少資料例如介紹api的都是官網的復刻節選,而我用MobX感受真的很爽,因此寫篇文章幫助初入MobX坑的玩家們,若是寫的不對,也但願各位指正,更好發展。javascript

適合用MobX的項目

我認爲能用redux的項目就能夠用mobx,除非須要redux-saga完成一些極其複雜的異步狀態改變,均可以完美替代,一些如微博之類偏社交的總體異步狀態併發改變可能不少,不太適合;像能分紅各個小模塊的,各模塊互相聯繫不是很緊密的複雜項目用mobx體驗很好。簡言之,因地制宜,不要無腦使用redux,每一個都有適合的環境。vue

基本知識儲備

基本的api詳細介紹

不使用嚴格模式的話,不會有Actions而是直接改observable的state,下面是佔出現率99%的apijava

  • @observer:用在react的view層的組件上方,變成可觀察的
  • @observable:把一個變量變成可觀察的
  • @computed:相似於vue,收集observable的變化而變化
  • autorun:包裹的函數先自動執行一次,裏面檢測到有依賴變更,自動執行
  • toJS(value, options?):把observable的對象變回原生js對象的函數(實際用的地方不多,但須要知道,若是是用4版本一下的仍是要特別注意)

網上比較多,也能夠移步MobX中文官網,安裝MobX和mobx-react還有裝飾器和對應的babel 官網資料也很清晰。react

想更好的理解MobX能夠找找網上的手寫MobX教程,也有助於理解本篇文章(PS:不少api手寫起來比想象的簡單,簡單說來就是把一個普通的深層對象經過遞歸層層綁定,變成observable的對象,實現最小細粒度的依賴收集)c++

另外,值得一提的就是MobX5使用的proxy,MobX4如下用的Object.defineProperty,仍是有點區別的,很少說了web

結合MVP思想使用

官網的圖⬇ redux

相比較redux狀態管理庫,這種單向流真的清晰容易理解,同時咱們團隊作了進一步簡化,不用Actions觸發,直接修改狀態state,但對其作了一些約定,使得代碼量進一步下降

咱們團隊使用mvp思想,這裏的mvp其實相似安卓的mvp思想,是mvc的兄弟,在MVC裏,View是能夠直接訪問Model的,但MVP中的View並不能直接使用Model,而是經過爲Presenter提供接口,讓Presenter去更新Model,再經過觀察者模式更新View。 與MVC相比,MVP模式經過解耦View和Model,徹底分離視圖和模型使職責劃分更加清晰;因爲View不依賴Model,能夠將View抽離出來作成組件,它只須要提供一系列接口提供給上層操做。mvp優勢是數據和視圖分得很開,缺點是若是邏輯多的話,presenter可能會很重,可是採用MobX的話會好不少,大量受觀察的數據能夠少寫些邏輯。MobX寫起來很簡單(代碼比redux少太多),邏輯也比較清晰,能夠在presenter裏面很快找到數據變更的邏輯api

上圖就是一個mvp思想下的模塊,整個模塊: Home這個tsx組件負責View,在constructor函數裏面new實例化Presenter.ts這個控制器(最好是這樣作,狀態組件能夠複用),presenter負責整個的數據處理邏輯,同時引入Home的子組件要把實例化後的presenter傳入,大致就是這些

下面用代碼簡單示意⤵️瀏覽器

View層GoodsPriceTrackHome.tsx代碼以下:bash

@observer
export default class GoodsPriceTrackHome extends React.Component<any, any> {
    private presenter: GoodsPriceTrackPresenter;
    constructor(props: any, context: any) {
        super(props, context);
        this.presenter = new GoodsPriceTrackPresenter();
    }
    //簡單示意
    render() {
        const {abc,changeAbc} = this.presenter;
        return <div onClick={changeAbc}> abc </div>
    }
    //若是有子組件且須要傳presenter的話
    render() {
        return <Children presenter={this.presenter} /> } 複製代碼

控制器這一層GoodsPriceTrackPresenter.ts代碼以下:

export default class GoodsPriceTrackPresenter {
    @observable
    public abc: number = 123;
    
    public changeAbc(){
        this.abc++;
    }
}
複製代碼

是否及什麼時候使用嚴格模式

結論:基本不用嚴格模式(像示例中直接改了this.abc),若是是兩三我的協做開發的小項目,開發過程當中基本沒有太多交集,天然不須要約定修改,大型項目的話,只有登陸等帳戶全局的一些異步操做須要嚴格模式@action來約束,其餘模塊的話,最多一兩我的來負責開發維護,因此若是基本上是本身負責一個模塊或者一個小項目,就直接用普通模式

注意事項

全部的與服務器通訊數據變更操做都放在p(presenter)上,除了監控ui的變化(如一些自適應之類)才放在v(view)上

React Native下mobx相對更好

React Native編譯後與h5或者web端這種瀏覽器是不一樣的,它對性能更敏感,每次刷新並非操做dom而是原生組件,因此 在大型列表等狀況下,MobX 能夠更新特定單元格而無需從新呈現整個列表。一般這也能夠經過 Redux 實現,可是須要重寫 componentShouldUpdate() 方法並編寫更多樣板文件以免沒必要要的從新渲染。在將其他變量複製到新狀態時,redux的reducer 仍會執行一些沒必要要的工做

MobX體驗的一些不足

1.開發插件

mobx因爲是分佈式的狀態管理,因此幾個開發插件體驗很差,基本沒怎麼用,調試是打斷點或者console,感受這樣更方便一些

2.內存泄漏

開發者水平不齊或者無心識的進行不規範的使用,可能會形成內存泄漏,用戶長時間使用產品形成內存泄漏,影響用戶體驗(組件卸載以後,可是其餘引用較亂,致使某些手觀察對象或者閉包沒法釋放)

3.侵入性

面向對象的話,設計較爲複雜,無關大量數據綁定太多,也會影響到性能

總結

1.基本不用嚴格模式約束,直接在Presenter組件裏改狀態(但怎麼改必定要事先理清思路哈)

2.相比redux,MobX管理狀態更簡單有效率,寫的代碼更少,作項目效率更高(但要分項目適不適合)

3.若是不注意使用規範,大項目可能會有性能問題(通常是遇不到的)

這篇文章我還會常常去完善更新,由於狀態庫涉及太多,講得比較草率,不少都點到即止了

歡迎評論區評論和拍磚,兩開花啊兩開花

相關文章
相關標籤/搜索