序言
umi
為什么使用Umi.js?
generator
生成器函數
yield 同步方式寫異步代碼
redux-saga
redux-saga是一個用於管理redux應用異步操作的中間件,redux-saga通過創建sagas將所有異步操作邏輯收集在一個地方集中處理,可以用來代替redux-thunk中間件。
Redux-saga是Redux的一個中間件,主要集中處理react架構中的異步處理工作,被定義為generator(ES6)的形式,采用監聽的形式進行工作。
dva
為什么要使用dva?
不得不說,當你寫過原生 React
后,會發現 Dva
寫起來真的是爽歪歪,他對 redux + react-router + redux-saga
進行了一層封裝,減少了很多代碼操作。同時加上 Umi 強大的路由處理功能,使得開發過程中又一次減少了不少踩坑操作。
正如 Dva 官網所言, Dva 是基於React + Redux + Saga的最佳實踐沉淀, 做了 3 件很重要的事情, 大大提升了編碼體驗。
其實使用React Hooks的目的就是為了去redux,那我為什么還會使用基於redux-soga封裝的dva呢?原因就在於hooks雖然很方便,但如果是一些很復雜的狀態需要去管理,這時候使用hooks就會有點兒費勁了。所以這時候結合dva來解決這種特別復雜的狀態管理是很方便的,原生的redux使用起來稍微有點兒麻煩,dva用起來很簡單,很爽,這就是我選擇dva的原因。
Dva數據流向
總的來說如下:View層操作 –> 觸發models層effect中方法 –> 觸發service層請求,獲取后台數據 –> 觸發model層處理相應數據的方法,存儲至reducer中 –> 更新model層中state –> 觸發view層的render方法進行重新渲染 –> 頁面更新
如何使用dav?
正如 Dva 官網所言, Dva 是基於 React + Redux + Saga 的最佳實踐沉淀, 做了 3 件很重要的事情, 大大提升了編碼體驗:
- 把 store 及 saga 統一為一個 model 的概念, 寫在一個 js 文件里面
- 增加了一個 Subscriptions, 用於收集其他來源的 action, eg: 鍵盤操作
- model 寫法很簡約, 類似於 DSL 或者 RoR, coding 快得飛起✈️

app.model({ namespace: 'count', state: { record: 0, current: 0, }, reducers: { add(state) { const newCurrent = state.current + 1; return { ...state, record: newCurrent > state.record ? newCurrent : state.record, current: newCurrent, }; }, minus(state) { return { ...state, current: state.current - 1}; }, }, effects: { *add(action, { call, put }) { yield call(delay, 1000); yield put({ type: 'minus' }); }, }, subscriptions: { keyboardWatcher({ dispatch }) { key('⌘+up, ctrl+up', () => { dispatch({type:'add'}) }); }, }, });
聊聊dva 中的 effects 與 reducers以及其中涉及的關鍵字的使用
使用dva+umi+antd構建頁面
編寫 UI Component
隨着應用的發展,你會需要在多個頁面分享 UI 元素 (或在一個頁面使用多次),在 umi 里你可以把這部分抽成 component 。
我們來編寫一個 ProductList component,這樣就能在不同的地方顯示產品列表了。
新建 src/components/ProductList.js 文件:
定義 dva Model
完成 UI 后,現在開始處理數據和邏輯。
dva 通過 model 的概念把一個領域的模型管理起來,包含同步更新 state 的 reducers,處理異步邏輯的 effects,訂閱數據源的 subscriptions 。
新建 model src/models/products.js,
connect 起來
到這里,我們已經單獨完成了 model 和 component,那么他們如何串聯起來呢?
dva 提供了 connect 方法。如果你熟悉 redux,這個 connect 來自 react-redux。
subscription:監聽派發,用於初始化數據源。
effects:異步派發,用於通過call接口把數據傳回來然后轉發。
reducer:處理返回,用於把傳過來的各類數據各種處理,然后返回。它是state的最后一步。
umi3+dva+typescript重新做一個用戶列表的增刪改查
但是() => Promise<any>到底是個什么類型呢?