React框架 dva 和 mobx 的使用感覺

最近在用react寫web項目,領導爲了讓前端便於維護要求都用react做爲開發基礎,框架選型不限。在使用 react 的時候或多或少會接觸到狀態管理,從開始學 react 到如今也挺久了,作一些前端框架選型總結。javascript

dva 
經朋友推薦開始接觸 dva ,從  2.x 版本開始使用,我也基於這個工具開發了一套項目模版,它簡化了 redux 的使用,而且在封裝了 redux-saga 和 react-router,同時還能夠包含 dva-loading 插件獲取 loading 狀態等。前端

在 redux 時代,當我須要新增一種跨頁面全局數據的時候,我須要去項目的 reducers 目錄定義一下這種數據命名和初始值,而後在 constans 目錄中爲更改這項數據的操做定義一種惟一的操做類型(type),再去 actions 目錄定義一些方法,這些方法最後會獲得更改後的數據和操做類型(type),最後再回到 reducers 中根據這個操做類型(type)把數據整合到 reducer 中…能夠看到,我在編寫 redux 這部分代碼的時候須要頻繁在 actions 、 constants 、 reducers 這幾個目錄間切換。java

而使用 dva 就能夠免除這些困擾了,我只須要一個 model 中就能夠完成全部操做:react

// app全局性狀態管理
import * as appApis from '../services/app'; // 異步請求接口

export default {
  namespace: 'app',

  state: {
    channels: [],
    show: true
  },

  reducers: {
    getChannelsAndGamesSuccess(state, { channels, games }) {
      return { ...state, channels, games };
    },
    changeShow(state, { show }) {
      return { ...state, show };
    }
  },

  effects: { // 異步
    * getChannelsAndGames(_, { call, put }) {
      const res = yield call(appApis.getChannelsAndGames);
      yield put({
        type: 'getChannelsAndGamesSuccess',
        channels: res.channels
      });
    }
  },
    
  subscriptions: { // 訂閱
    setup({dispatch, history}) {
      history.listen(location => {
        if (location.pathname == '/') {
          dispatch({
            type: 'getChannelsAndGames'
          });
        }
      });
    }    
  }
};

  

這即是一個 model 對象,state 定義數據、effects 中執行異步請求、觸發 action 在 reducers 中改變數據,一鼓作氣!git

此外它還含有其餘特性,好比:subscription(訂閱),能夠在這裏訂閱 history 路由變化,進入根路徑執行 getChannelsAndGames 獲取數據,而不須要在 react 的生命週期中作這些事;用上 dva-loading 插件,在更改數據的過程當中還會自動設置 loading 狀態,這在異步請求中很是有用!github

dva官網:https://github.com/dvajs/dva/blob/master/README_zh-CN.mdweb

mobx

既然 dva 這麼好用,爲何還要使用 mobx 呢?還不是爲了折騰😅,用了才能知道二者的優劣,一樣的基於 mobx 我也建立了一個項目模版。redux

在使用 dva 的時候,但凡遇到異步請求的時候都須要先定義一個 effects ,請求完成後再觸發一個 action 去修改數據,因而,強迫症做怪,這二者的命名老是讓我感受難受和囉嗦,你能夠看到我都是定義爲 getXxx 和 getXxxSuccess前端框架

action 是修改 state 的惟一途徑,是的,全部的狀態管理庫都是這樣的,可是 mobx 經過一些工具函數解決了這一問題:react-router

// app全局性狀態管理
import { observable, action, runInAction } from 'mobx';
import * as appApis from '../services/app';

export default class AppStore {
  @observable show = true;
  @observable list = [];

  @action toggleShow = () => { this.show = !this.show; }
  @action getData = async (params) => {
    try {
      const res = await appApis.getTopicsList(params);
      // await 以後,再次修改狀態須要動做: 
      runInAction(() => {
        this.list = res.data;
      });
    } catch (e) {
      console.error(e);
    }
  }
}

/**
 * -----------------------------------------------------------------
 */
// app全局性狀態管理
import { observable, action } from 'mobx';
import { asyncAction } from "mobx-utils"
import * as appApis from '../services/app';

export default class AppStore {
  @observable show = true;
  @observable list = [];

  @action toggleShow = () => { this.show = !this.show; }
  @asyncAction * getData(params) { // <- 注意*號,這是一個 generator 函數!
    try {
      const res = yield appApis.getTopicsList(params); // 用 yield 代替 await
      this.list = res.data;
    } catch (e) {
      console.error(e);
    }
  }
}

  

以上是我最喜歡的兩種寫法,分別藉助了 runInAction 和 asyncAction 這兩個工具函數,固然,還有其餘方法能夠參考。

mobx官網:http://cn.mobx.js.org/

總結

不論是 redux 、 dva ,仍是 mobx ,每種技術的出現都是爲了帶給咱們更好的開發體驗、更高的開發效率,也伴隨着不同的學習成本,雖然 mobx 能夠治好個人強迫症,可是也反逼我去學習了修飾器;雖然看起來 redux 是最繁瑣的,可是它多是對新手最友好的,參考資料也是最多的,也可以一步步讓我知道狀態是如何改變的,再者,若是我沒使用過 redux ,未必能體會到後二者帶給我怎樣的便利之處。

還有這個UI組件工具也必不可少:

https://ant.design/docs/react/introduce-cn

相關文章
相關標籤/搜索