MobX or Redux?

前言

在過去的項目中一直用的都是Redux,以爲挺不錯的,按照官方推薦的一些寫法,再加上團隊風格,打造了一套關於Redux的架構,可是,如今以爲寫Action、Reducer太繁瑣,隨着業務不斷的增量,相應的文件和代碼也會不斷的增長,並且對新人來講不是很是友好(理解Redux比較困難),據說一方諸侯MobX很是不錯,因此在嘗試使用了,目前項目中兩套架構都是並存,寫下本身的一些感想。vue

都解決什麼問題?

一、組件之間複用狀態很是困難react

React自己沒有提供將可複用性狀態「附加」到組件的途徑(例如,把組件鏈接到 store)。若是你使用過 React 一段時間,你也許會熟悉一些解決此類問題的方案,好比 props 和 HOC。可是這類方案須要從新組織你的組件結構,這可能會很麻煩,使你的代碼難以理解。寫下這片博客的時候,React已提供Hook,可是本人以爲這都是些hack方案。git

二、複雜組件變得難以理解github

咱們常常維護一些組件,組件起初很簡單,可是逐漸會被狀態邏輯和反作用充斥。每一個生命週期經常包含一些不相關的邏輯。例如,組件經常在 componentDidMount 和 componentDidUpdate 中獲取數據。可是,同一個 componentDidMount 中可能也包含不少其它的邏輯,如設置事件監聽,而以後需在 componentWillUnmount 中清除。相互關聯且須要對照修改的代碼被進行了拆分,而徹底不相關的代碼卻在同一個方法中組合在一塊兒。如此很容易產生 bug,而且致使邏輯不一致。web

在多數狀況下,不可能將組件拆分爲更小的粒度,由於狀態邏輯無處不在。編程

Redux

Redux由Flux演變而來,但受 Elm 的啓發,避開了 Flux 的複雜性。它主要有如下三個核心概念:redux

一、Actionsapi

一個JavaScript對象,描述發生的動做,主要包含type和payload兩個屬性。 payload能夠是普通的數據或是函數。數組

const GET_LIST = 'getList';
return {
        type: GET_LIST,
        payload: api.getList(params)
};
複製代碼

二、Reducerpromise

定義應用狀態如何響應不一樣動做(action),如何更新狀態;

switch (action.type) {
  case GET_LIST:
  	return Object.assign({}, state, { list: action.payload.result });
  default:
        retur state;
}
複製代碼

三、Store

const initialState = {
    orderListData: {}
};
複製代碼

存儲組件的數據,主要提供如下功能:

3.1.維護應用狀態並支持訪問狀態(getState());

3.2.支持監聽action的分發,更新狀態(dispatch(action));

3.3.支持訂閱store的變動(subscribe(listener));

四、異步流

因爲Redux全部對store狀態的變動,都應該經過action觸發,異步任務(一般都是業務或獲取數據任務)也不例外,而爲了避免將業務或數據相關的任務混入React組件中,就須要使用其餘框架配合管理異步任務流程,如redux-thunk、redux-saga、redux-promise。

五、數據流向

4589e5a96d296d189fd43f38331195f

MobX

MobX 是一個通過戰火洗禮的庫,它經過透明的函數響應式編程(transparently applying functional reactive programming - TFRP)使得狀態管理變得簡單和可擴展。其中核心概念也很是簡單,主要有如下幾個:

一、Store

使用 observable 很像把對象的屬性變成excel的單元格。 但和單元格不一樣的是,這些值不僅是原始值,還能夠是引用值,好比對象和數組。

import { observable } from "mobx";

class Todo {
    @observable title = '';
}
複製代碼

二、Computed values

當添加了一個新的todo或者某個todo的 finished 屬性發生變化時,MobX 會確保 unfinishedTodoCount 自動更新。 像這樣的計算能夠相似於 MS Excel 這樣電子表格程序中的公式。每當只有在須要它們的時候,它們纔會自動更新。

class TodoList {
    @observable todos = [];
    @computed get unfinishedTodoCount() {
        return this.todos.filter(todo => !todo.finished).length;
    }
}
複製代碼

三、Reactions

Reactions和計算值很像,但它不是產生一個新的值,而是會產生一些反作用,好比打印到控制檯、網絡請求、遞增地更新 React 組件樹以修補DOM、等等。

autorun(() => {
    console.log("Tasks left: " + todos.unfinishedTodoCount)
})
複製代碼

四、Actions

描述要發生的動做

class TodoList {
    @observable title = '';

    @action
    changeTitle() {
        this.title = 'test';
    }
}
複製代碼

五、異步流

MobX不須要額外配置另外的庫。

六、數據流向

3b0a68d54ff53abcf1e64873e962b34

Redux優勢

一、流程規範,按照官方推薦的規範和結合團隊風格打造一套屬於本身的流程。

二、函數式編程,在reducer中,接受輸入,而後輸出,不會有反作用發生,冪等性。

三、可追蹤性,很容易追蹤產生BUG的緣由。

Redux缺點

一、流暢太繁瑣,須要寫各類action,reducer。

二、要想完成異步數據,得配合其餘庫。

MobX優勢

一、學習成本少,基礎知識很是簡單,跟vue同樣的核心原理,響應式編程。

二、寫更少的代碼,完成更多的事。不會跟Redux同樣寫很是多的樣板代碼。

三、使組件更加顆粒化拆分。

MobX缺點

一、過於自由,MobX提供的約定及模版代碼不多,若是團隊不作一些約定,容易致使團隊代碼風格不統一。

二、可拓展,可維護性,也許你會擔憂Mobx能不能適應後期項目發展壯大呢?確實Mobx更適合用在中小型項目中,但這並不表示其不能支撐大型項目,關鍵在於大型項目一般須要特別注意可拓展性,可維護性,相比而言,規範的Redux更有優點,而Mobx更自由,須要咱們本身制定一些規則來確保項目後期拓展,維護難易程度;

架構案例

Redux腳手架

MobX腳手架

最後思考

對於Redux更規範,更靠譜,應該使用Redux或Redux模版太多,太複雜了,應該選擇Mobx這類推斷,咱們都應該避免,也應該要避免這些,這些都是相對而言,每一個框架和庫都有各自的實現,特點,及其適用場景,正如Redux流程更復雜,但熟悉流程後就更能把握它的一些基礎/核心理念,使用起來可能更有心得及感悟;而Mobx簡單化,把大部分東西隱藏起來,若是不去特別研究就不能接觸到它的核心/基本思想,也許使得開發者一直停留在使用層次。

因此不管是技術棧仍是框架類庫,並無絕對的比較咱們就應該選擇什麼,拋棄什麼,咱們應該更關注它們解決什麼問題,它們解決問題的關注點,或者說實現方式是什麼,它們的優缺點還有什麼,哪個更適合當前項目,以及項目將來發展。

參考

一、你須要Mobx仍是Redux?

二、MobX

三、React

四、Redux

相關文章
相關標籤/搜索