React native 項目進階(redux, redux saga, redux logger)

以前利用知乎日報的api寫了react-native的一個入門項目,傳送文章地址React Native 項目入門和源碼地址RN入門項目源碼,目前github上的代碼已經在原文的基礎上增長了新的功能,也就是本文進階的內容,看完本文感興趣的同窗能夠參考一下。javascript

思考

在入門項目中咱們已經實踐了React native 的基本用法,展現了知乎日報的列表和詳情頁。在小型的項目中這樣實踐固然是沒有問題的,咱們在每一個頁面中自行請求網絡,渲染組件,徹底能夠。可是當項目變得複雜,須要增長新的feather或者擴展log日誌等基礎模塊時,這樣的實踐絕對讓人苦不堪言,事倍功半。html

從維護和功能擴展等角度來講,項目使用合適的框架是必需的。咱們從日誌入手來分析,好比咱們須要記錄系統中全部訪問網絡的日誌,若是每一個頁面中使用fetch訪問網絡,則log須要記錄在每一個頁面中進行記錄:
java

1.png

一種進階的方法是封裝網絡請求方法,日誌記錄統一封裝模塊中進行設置:
2.png

這種方法已經能夠應付大部分狀況,當log需求更改時,只需跟新一個模塊便可。react

若是這時須要增長數據庫訪問的日誌,咱們按照相同的思路,能夠定義一個數據庫訪問的模塊,在該模塊中定義相應的日誌模塊。若是須要增長更多類型的日誌模塊呢,是繼續按照一樣的思路繼續嗎?git

咱們看一下剛提到的兩種日誌,提取一下共同點,都須要記錄日誌,咱們有沒有可能提取一個日誌模塊,圖示一下思路:
github

3.png

假如這時又有一個需求是記錄一下全部操做的執行時間,並根據執行時間的統計對相應的系統參數進行調整,這時候怎麼解決呢,圖示思路,咱們能夠在中間繼續增長一個模塊:
數據庫

4.png

以上均是一些簡單的思路,在具體工程實踐中應該怎麼作呢?咱們先來看一下Flux的思路。

Flux

5.png

咱們先來看一下Flux中的幾個角色:

  • View: 視圖層
  • Action(動做):視圖層發出的消息(好比mouseClick)
  • Dispatcher(派發器):用來接收Actions、執行回調函數
  • Store(數據層):用來存放應用的狀態,一旦發生變更,就提醒Views要更新頁面

其基本思路是對全部的動做進行封裝,而後使用dispatcher對動做進行分發,在Store中完成處理後傳遞給View,完成一次完整數據流動,此流動爲單向,不可逆。
其中Action咱們理解爲動做,此動做不只包括動做類型(即目標,記錄日誌仍是計算任務執行時間),同時還能夠攜帶必定的數據,參照以上咱們的思路圖4,很是符合咱們的需求。redux

Redux

Redux 實際是flux思路的一種實現,在角色定義方面略有不一樣,可是不妨礙思路相同。react-native

  • Action(動做) 與flux中的定義相似
  • reducer 對Action中定義是state進行更新,注意流程中只能經過reduce進行更新,同時reducer要保證爲純函數,即對於必定對輸入,必定能夠得到相應的輸出,而不會受到時間或者所以的影響。
  • store store 實際完成了dispatcher的功能,同時鏈接了其餘功能模塊。

    維持應用的 state;
    提供 getState() 方法獲取 state;
    提供 dispatch(action) 方法更新 state;
    經過 subscribe(listener) 註冊監聽器;
    經過 subscribe(listener) 返回的函數註銷監聽器。api

redux還有一個重要的概念:中間件,中間件能夠在數據傳遞過程當中進行一些額外的動做,如上文提到的日誌記錄等功能。至此,咱們能夠利用redux完成咱們須要的功能。本文主要介紹思路,關於redux的具體學習推薦阮一峯老師的博客,Redux 入門教程

redux-saga

咱們知道在應用中必定會有不少異步操做,如網絡訪問、數據讀取等,redux完成了數據的傳遞,可是在異步操做部分若是咱們不加註意,可能會寫出一團糟的代碼,redux-saga正完成了這件事情。

Sagas 負責協調那些複雜或異步的操做。

項目實踐

本文的項目進階就是在代碼中加入對redux的支持,固然按照本項目的需求增長這些是沒有必要的,只是徒增了項目的複雜度。這裏主要演示redux以及中間件redux-saga, redux-logger在項目中的使用。其中saga在以上已經進行了介紹,redux logger 實際是對全部Action state 進行了紀錄,進行項目debug時,咱們能夠根據console的log輸出判斷項目的具體state變化:

Paste_Image.png

  • store 的建立
const middlewares = [];
// 建立reducer
const rootReducer = combineReducers({story});
// 建立中間件saga
const sagaMiddleware = saga();

middlewares.push(sagaMiddleware)
if (process.env.NODE_ENV === 'development') {
    //建立中間件logger
    const logger = createLogger();
    middlewares.push(logger);
}
//applymiddleware配置中間件
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);

function createDefaultStore(initialsState) {
    //經過reducer 獲取stare
    const defaultStore = createStoreWithMiddleware(rootReducer, initialsState);
    return defaultStore;
}
const store = createDefaultStore();複製代碼
  • Reducers的建立
    能夠建立多個reducers,經過

    combineReducers();複製代碼

    進行組合

    const initialState = {
      id: "",
      refreshing: true,
      loaded: false,
      story: new Object()
    };
    export default function story(state = initialState, action) {
      switch (action.type) {
          case ActionType.Fetch_Story_Detail:
              return Object.assign({}, state, {
                  id: action.id,
                  refreshing: true,
                  loaded: false
              });
          case ActionType.Fetch_Story_Detail_Done:
              return Object.assign({}, state, {
                  id: action.id,
                  refreshing: false,
                  load: true,
                  story: action.story
              });
          default:
              return state;
      }
    }複製代碼

    如上建立store reducer

  • connect
    界面組件須要connect redux,能夠dispatch Actions,同時能夠接收到相應的回調,完成界面的render。

    function mapStateToProps(state) {
      const {story} = state;
      return {
          story
      };
    }
    StoryDetailPage.propTypes = propTypes;
    export default connect(mapStateToProps)(StoryDetailPage);複製代碼

    通過這幾步,咱們項目的結構就很是清晰了,在進行模塊維護和擴展時就很方便了。

代碼地址:react-native-zhihu

歡迎關注公衆號wutongke,天天推送移動開發前沿技術文章:

wutongke

推薦閱讀:

React-native項目入門與思考
React native 項目入門(知乎日報,豆瓣電影,[one]一個)
React native 項目進階(redux, redux saga, redux logger)

React Native 項目2(One 【一個】客戶端)

感謝:
www.ruanyifeng.com/blog/2016/0…
www.ruanyifeng.com/blog/2016/0…
github.com/kenberkeley…
leonshi.com/redux-saga-…
cn.redux.js.org/index.html

相關文章
相關標籤/搜索