dva工具庫---探索dva-loading

前言

在使用antd pro的時候發現此框架的loading是使用dva自帶的dva-loading。之前分析源碼的時候有看見幾個附帶工具,但沒有去研究下。今天好奇下dva-loading的實現。

開始

先從用法了解
loading是針對effects的,所以我們所有需要顯示loading的異步操作都需要寫在effects中才可以體現dva-loading的方便性,下面例子中,loading是針對namespace為form的model的submitStepForm的effect,

import createLoading from 'dva-loading';
...
app.use(createLoading());


...

@connect(({ form, loading }) => ({
  submitting: loading.effects['form/submitStepForm'],
  data: form.step,
}))

app.use是什么,從源碼里知道,就是plugin.use,注冊對應的插件鉤子的。所以createLoading返回的是

return {
    extraReducers,
    onEffect,
  };

extraReducers:加一個state,默認名字是loading,可以createLoading時傳入{namespace:xxx}去覆蓋。

onEffect:是為了包裝所有的effect,在執行前后發出供上面reducers接收的action。

所以先看前置onEffect

  1. 前面的if的條件是外部傳入的,可用此進行優化,不然所有的effect都被重包裝
  2. 目標effect執行前,發出SHOW類型的action,結束后發出HIDE
  3. payload是model的namespace及effect的名字(在之前收集的時候,已經給所有的effect加上namespace前綴)。上面的例子就是{namespace:'form',actionType :'form/submitStepForm'}
function onEffect(effect, { put }, model, actionType) {
    const { namespace } = model;
    if (
        (only.length === 0 && except.length === 0)
        || (only.length > 0 && only.indexOf(actionType) !== -1)
        || (except.length > 0 && except.indexOf(actionType) === -1)
    ) {
        return function*(...args) {
            yield put({ type: SHOW, payload: { namespace, actionType } });
            yield effect(...args);
            yield put({ type: HIDE, payload: { namespace, actionType } });
        };
    } else {
        return effect;
    }
  }

到 extraReducers

  1. state說明,從內到外,effects:可知道有哪些effect在loading,models:可知道有哪些model在loading,gobal有沒有在的loading的effect。可以知道后面兩個可以從第一個推理得出,但dva幫我們算出來,有這兩個確認會方便,比如一個功能的數據由一個model(kk)控制,這就可以不管有多少effect,都可以從loading.models['kk']中獲得該功能的loading狀態。
  2. 當接收到SHOW的action,會:保存payload里的namespace與actionType,并設為true,表示namespace的model和actionType的effect在加載,global一定為true,有在進行effect
  3. 當接收到HIDE的action,會: 把這個payload的effect名稱actionType設為false,表示該effect加載完,如果effects中找到有namespace前綴的在loading的effect,則該model也在loading中,如果models中找到有model在loading,則該全局loading中

 const initialState = {
    gobal: false, // 有沒有在的loading的effect
    models: {}, // 可知道有哪些model在loading
    effects: {}, // 可知道有哪些effect在loading
  };

  const extraReducers = {
    [namespace](state = initialState, { type, payload }) {
      const { namespace, actionType } = payload || {};
      let ret;
      switch (type) {
        // 保存payload里的namespace與actionType,并設為true,表示namespace的model和actionType的effect在加載,
        // global一定為true,有在進行effect
        case SHOW:
          ret = {
            ...state,
            global: true,
            models: { ...state.models, [namespace]: true },
            effects: { ...state.effects, [actionType]: true },
          };
          break;
        case HIDE: // eslint-disable-line
        //  把這個payload的effect名稱actionType設為false,表示該effect加載完
          const effects = { ...state.effects, [actionType]: false };
          // 如果effects中找到有namespace前綴的在loading的effect,則該model也在loading中
          const models = {
            ...state.models,
            [namespace]: Object.keys(effects).some((actionType) => {
              const _namespace = actionType.split('/')[0];
              if (_namespace !== namespace) return false;
              return effects[actionType];
            }),
          };
          // 如果models中找到有model在loading,則該全局loading中
          const global = Object.keys(models).some((namespace) => {
            return models[namespace];
          });
          ret = {
            ...state,
            global,
            models,
            effects,
          };
          break;
        default:
          ret = state;
          break;
      }
      return ret;
    },
  };

done

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 筆者升級了 dva 的版本,同時新增了 umi 的使用,具體可以參考這篇文章 dva理論到實踐——幫你掃清dva的...
    darrell閱讀 40,292評論 8 86
  • dva框架的使用詳解及Demo教程 在前段時間,我們也學習講解過Redux框架的基本使用,但是有很多同學在交流群里...
    光強_上海閱讀 61,275評論 5 55
  • 前言 在學習antd的UI框架時,了解到了dva這個輕量級的應用框架,集成了react,redux,redux-s...
    Gary嘉駿閱讀 3,395評論 1 2
  • 麥祺的禮物: 男人愛女人, 女人愛男人, 窮, 女人有非常漂亮的頭發, 沒有發卡; 男人有一塊祖傳的表, 沒有表鏈...
    Sarah瀟瀟閱讀 435評論 0 0
  • 我的淚------眼角無聲的滑落 初秋的夜 心卻被冰封凍 句句帶刺的話語 針針扎入結痂的裂心 這夜色化不開郁結的悶...
    靜若青蓮閱讀 377評論 0 5