在過去的項目中一直用的都是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由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。
五、數據流向
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不須要額外配置另外的庫。
六、數據流向
一、流程規範,按照官方推薦的規範和結合團隊風格打造一套屬於本身的流程。
二、函數式編程,在reducer中,接受輸入,而後輸出,不會有反作用發生,冪等性。
三、可追蹤性,很容易追蹤產生BUG的緣由。
一、流暢太繁瑣,須要寫各類action,reducer。
二、要想完成異步數據,得配合其餘庫。
一、學習成本少,基礎知識很是簡單,跟vue同樣的核心原理,響應式編程。
二、寫更少的代碼,完成更多的事。不會跟Redux同樣寫很是多的樣板代碼。
三、使組件更加顆粒化拆分。
一、過於自由,MobX提供的約定及模版代碼不多,若是團隊不作一些約定,容易致使團隊代碼風格不統一。
二、可拓展,可維護性,也許你會擔憂Mobx能不能適應後期項目發展壯大呢?確實Mobx更適合用在中小型項目中,但這並不表示其不能支撐大型項目,關鍵在於大型項目一般須要特別注意可拓展性,可維護性,相比而言,規範的Redux更有優點,而Mobx更自由,須要咱們本身制定一些規則來確保項目後期拓展,維護難易程度;
對於Redux更規範,更靠譜,應該使用Redux或Redux模版太多,太複雜了,應該選擇Mobx這類推斷,咱們都應該避免,也應該要避免這些,這些都是相對而言,每一個框架和庫都有各自的實現,特點,及其適用場景,正如Redux流程更復雜,但熟悉流程後就更能把握它的一些基礎/核心理念,使用起來可能更有心得及感悟;而Mobx簡單化,把大部分東西隱藏起來,若是不去特別研究就不能接觸到它的核心/基本思想,也許使得開發者一直停留在使用層次。
因此不管是技術棧仍是框架類庫,並無絕對的比較咱們就應該選擇什麼,拋棄什麼,咱們應該更關注它們解決什麼問題,它們解決問題的關注點,或者說實現方式是什麼,它們的優缺點還有什麼,哪個更適合當前項目,以及項目將來發展。
二、MobX
三、React
四、Redux