1. 程式人生 > >SaaS管理系統開發經驗------Dva(Redux)實戰經驗分享

SaaS管理系統開發經驗------Dva(Redux)實戰經驗分享

寫在前面

SaaS 2.1 已經開發結束了,時間早已過去了好幾個月,今天若是說從Dva基礎入門講起的話,實在沒必要 ,沒有比官網上的作者自己的介紹更專業更詳盡了,既然這個系列想說的是實戰經驗,那今天就把Dva 在實戰中總結一下,向各位大佬求證一下:

Dva封裝了Redux和Redux-saga,最大限度地精簡了Redux ,所以在記錄實戰經驗的時候是視他們為一體的。

一些細節

1. Dva的modal是需要註冊的。

特別是剛入門Dva的時候,很大可能會遇到由於忘記註冊modal而抓狂到懷疑人生的;

    app.model(require('./models/global'
).default); 複製程式碼
2. Modal的拆分---業務層還是資料層。
3. effect中的方法是可以跨Modal中呼叫的,但是要宣告名稱空間。
export default {
  namespace: 'user',
  state: {
    identity: 0,
    locale:'zh_CN',
  },

  effects: {
    * handleChangeIdentity({ payload, callback }, { call, put }) {
      const response = yield call(getChangeIdentity, payload);
      yield put({ type
: 'doChangeIdentity', payload: response.data }); // 這裡通過名稱空間account呼叫 account這個Modal的方法 yield put({ type: 'account/doChangeIdentity', payload: response.data }); } ... } ... } 複製程式碼
4. 元件中可以直接呼叫reducer中的方法,來更改Modal中的state,從而重新整理頁面。

也意味著同一個Modal內effect中的方法名不要和reducer中的方法名重複。

5. effect中的拿state中的資料---select。
effects: {
    * handleChangeIdentity(_, { call, put , select}) {
      // 這裡通過select方法拿取state中的資料
      const identity=yield select(state=>state.user.identity);
      const response = yield call(getChangeIdentity, {identity});
      ...
    }
    ...
}

複製程式碼

注意這裡的state不是當前Modal的state,而是最頂層的state

6. Modal中方法命名經驗:handle--get/post---do。

由於一個介面請求需要定義三個方法:方法呼叫effect,執行請求service,改變state reducer,所以為了方便追蹤採用effect裡使用handleXXX命名,service使用get/postXXX命名, reducer裡採用doXXX命名。

從此再也不用為方法太多,命名發愁了

關於使用HashHistory還是BrowserHistory

使用 hashHistory,瀏覽器上看到的 url 會是這樣的: /#/user/hai?pk=ads

使用 browserHistory,瀏覽器上看到的 url 會是這樣的:/user/hai

當然看起來 browserHistory 很好很理想,但 browserHistory 需要 server 端支援,就PWA(單頁)應用來講,是不太合適的, 畢竟單頁應用的路由是自己控制的。

而使用hashHistory的時候,因為 url 中 # 符號的存在,從 /#/ 到 /#/user/haishanh 瀏覽器並不會去傳送一次 request, react-router 自己根據 url 去 render 相應的模組。

如果使用 browserHistory 的時候,瀏覽器從 / 到 /user/haishanh 是會向 server 傳送 request 的。 所以 server 端是要做特殊配置的。比如用的 express 的話,你需要 handle 所有的路由 app.get('*', (req, res) => { ... }), 使用了 nginx 的話,nginx也要做相應的配置。

單向資料流之Modal中的state 與元件中的state

安裝Redux單向資料流的設計思想,資料流向為:dispatch開始請求資料----->reducer接收資料更新state----->頁面重新整理,也就是整個專案共同維護一個state樹----store,也就是說元件內部不該有state,這樣更符合Redux單向資料流思想。開發中發現一些頁面臨時資料比如一個彈窗顯示隱藏都需要dispatch一個action,然後reducer裡更新state,要橫跨好幾檔案,開發效率也跟著降低了。所以最後採取了一個折中一點的方法,一些頁面內部狀態之類的臨時資料還是放元件內部State。

除開一些元件臨時狀態使用本地state,其他state都應該屬於全域性。

當然這也引入下一個問題:當元件內部狀態需要根據後臺資料改變時怎麼處理?這就是下一個問題....

關於Dva effect回撥修改本地state

接上回書:當元件內部狀態需要根據後臺資料改變時,可以採用回撥的方式解決。

  getNotice = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'workbench/handleGetNotice',
      payload: {
        isRead: 0,
      },
      // 在action傳遞一個callback方法作為回撥
      callback: (data) => {
        this.setState({
            visible:data.isOk
        });
      },
    });
  };
  
  handleGetNotice({ payload,callback }, { call, put }) {
    const response = yield call(getNotice, a);
    // 在收到資料時執行回撥方法
    callback&&callback(response.data);
    
  }
  
複製程式碼

這裡特別注意:不要因為這裡可以執行回撥改變state,而偷懶將state全部放元件裡,如此就違背了Redux單向資料流,如此你又何必煞費苦心使用Redux呢?我想Dva作者不會再官網推薦這種寫法,大概是因為它確實違背了單向資料流的紅線,而我也只是在極其複雜的情況下才用過幾次,應急之用罷了。

今天就想到這麼多了,以後如果想起別的再來補上吧。也請各位行家裡手不吝賜教!