Dva數(shù)據(jù)流概念

dva 首先是一個基于 reduxredux-saga 的數(shù)據(jù)流方案泡躯,然后為了簡化開發(fā)體驗,dva 還額外內(nèi)置了 react-routerfetch崎逃,所以也可以理解為一個輕量級的應用框架。

特性

  • 易學易用眉孩,僅有 6 個 api个绍,對 redux 用戶尤其友好,配合 umi 使用后更是降低為 0 API
  • elm 概念浪汪,通過 reducers, effects 和 subscriptions 組織 model
  • 插件機制巴柿,比如 dva-loading 可以自動處理 loading 狀態(tài),不用一遍遍地寫 showLoading 和 hideLoading
  • 支持 HMR死遭,基于 babel-plugin-dva-hmr 實現(xiàn) components广恢、routes 和 models 的 HMR

安裝dva-cli

通過 npm 安裝 dva-cli 并確保版本是 0.9.1 或以上。

$ npm install dva-cli -g
$ dva -v
dva-cli version 0.9.1

使用antd

通過 npm 安裝 antdbabel-plugin-import 呀潭。babel-plugin-import 是用來按需加載 antd 的腳本和樣式的钉迷,詳見 repo 至非。

$ npm install antd babel-plugin-import --save

編輯 .webpackrc,使 babel-plugin-import 插件生效糠聪。

{
+  "extraBabelPlugins": [
+    ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
+  ]
}

注:dva-cli 基于 roadhog 實現(xiàn) build 和 dev荒椭,更多 .webpackrc 的配置詳見 roadhog#配置

定于Model

處理數(shù)據(jù)和邏輯。

dva 通過 model 的概念把一個領域的模型管理起來舰蟆,包含同步更新 state 的 reducers趣惠,處理異步邏輯的 effects,訂閱數(shù)據(jù)源的 subscriptions 身害。

新建 model models/products.js :

export default {
  namespace: 'products',
  state: [],
  reducers: {
    'delete'(state, { payload: id }) {
      return state.filter(item => item.id !== id);
    },
  },
};

這個 model 里:

  • namespace 表示在全局 state 上的 key
  • state 是初始值味悄,在這里是空數(shù)組
  • reducers 等同于 redux 里的 reducer,接收 action塌鸯,同步更新 state

dva提供了connect方法侍瑟。如果你熟悉redux,這個connect就是react-redux的connect界赔。

例子和腳手架

可查看官方及社區(qū)的例子和腳手架

Dva 概念

數(shù)據(jù)流向

數(shù)據(jù)的改變發(fā)生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉(zhuǎn)等)觸發(fā)的丢习,當此類行為會改變數(shù)據(jù)的時候可以通過 dispatch 發(fā)起一個 action,如果是同步行為會直接通過 Reducers 改變 State 淮悼,如果是異步行為(副作用)會先觸發(fā) Effects 然后流向 Reducers 最終改變 State咐低,所以在 dva 中,數(shù)據(jù)流向非常清晰簡明袜腥,并且思路基本跟開源社區(qū)保持一致(也是來自于開源社區(qū))见擦。

dva

Models

State

type State = any
State 表示 Model 的狀態(tài)數(shù)據(jù),通常表現(xiàn)為一個 javascript 對象(當然它可以是任何值)羹令;操作的時候每次都要當作不可變數(shù)據(jù)(immutable data)來對待鲤屡,保證每次都是全新對象,沒有引用關系福侈,這樣才能保證 State 的獨立性酒来,便于測試和追蹤變化。

在 dva 中你可以通過 dva 的實例屬性 _store 看到頂部的 state 數(shù)據(jù)肪凛,但是通常你很少會用到:

const app = dva();
console.log(app._store); // 頂部的 state 數(shù)據(jù)

Action

type AsyncAction = any
Action 是一個普通 javascript 對象堰汉,它是改變 State 的唯一途徑。無論是從 UI 事件伟墙、網(wǎng)絡回調(diào)翘鸭,還是 WebSocket 等數(shù)據(jù)源所獲得的數(shù)據(jù),最終都會通過 dispatch 函數(shù)調(diào)用一個 action戳葵,從而改變對應的數(shù)據(jù)就乓。action 必須帶有 type 屬性指明具體的行為,其它字段可以自定義,如果要發(fā)起一個 action 需要使用 dispatch 函數(shù)生蚁;需要注意的是 dispatch 是在組件 connect Models以后噩翠,通過 props 傳入的。

dispatch({
  type: 'add',
});
dispatch 函數(shù)

type dispatch = (a: Action) => Action
dispatching function 是一個用于觸發(fā) action 的函數(shù)守伸,action 是改變 State 的唯一途徑绎秒,但是它只描述了一個行為,而 dipatch 可以看作是觸發(fā)這個行為的方式尼摹,而 Reducer 則是描述如何改變數(shù)據(jù)的见芹。

在 dva 中,connect Model 的組件通過 props 可以訪問到 dispatch蠢涝,可以調(diào)用 Model 中的 Reducer 或者 Effects玄呛,常見的形式如:

dispatch({
  type: 'user/add', // 如果在 model 外調(diào)用,需要添加 namespace
  payload: {}, // 需要傳遞的信息
});
Reducer

type Reducer<S, A> = (state: S, action: A) => S
Reducer(也稱為 reducing function)函數(shù)接受兩個參數(shù):之前已經(jīng)累積運算的結果和當前要被累積的值和二,返回的是一個新的累積結果徘铝。該函數(shù)把一個集合歸并成一個單值。

Reducer 的概念來自于是函數(shù)式編程惯吕,很多語言中都有 reduce API惕它。如在 javascript 中:

[{x:1},{y:2},{z:3}].reduce(function(prev, next){
    return Object.assign(prev, next);
})
//return {x:1, y:2, z:3}

在 dva 中,reducers 聚合積累的結果是當前 model 的 state 對象废登。通過 actions 中傳入的值淹魄,與當前 reducers 中的值進行運算獲得新的值(也就是新的 state)。需要注意的是 Reducer 必須是純函數(shù)堡距,所以同樣的輸入必然得到同樣的輸出甲锡,它們不應該產(chǎn)生任何副作用茶袒。并且弄慰,每一次的計算都應該使用immutable data,這種特性簡單理解就是每次操作都是返回一個全新的數(shù)據(jù)(獨立疗涉,純凈)易稠,所以熱重載和時間旅行這些功能才能夠使用缸废。

Effect

Effect 被稱為副作用,在我們的應用中驶社,最常見的就是異步操作企量。它來自于函數(shù)編程的概念,之所以叫副作用是因為它使得我們的函數(shù)變得不純衬吆,同樣的輸入不一定獲得同樣的輸出。

dva 為了控制副作用的操作绳泉,底層引入了redux-sagas做異步流程控制逊抡,由于采用了generator的相關概念,所以將異步轉(zhuǎn)成同步寫法,從而將effects轉(zhuǎn)為純函數(shù)冒嫡。至于為什么我們這么糾結于 純函數(shù)拇勃,如果你想了解更多可以閱讀Mostly adequate guide to FP,或者它的中文譯本JS函數(shù)式編程指南孝凌。

Subscription

Subscriptions 是一種從 獲取數(shù)據(jù)的方法方咆,它來自于 elm。

Subscription 語義是訂閱蟀架,用于訂閱一個數(shù)據(jù)源瓣赂,然后根據(jù)條件 dispatch 需要的 action。數(shù)據(jù)源可以是當前的時間片拍、服務器的 websocket 連接煌集、keyboard 輸入、geolocation 變化捌省、history 路由變化等等苫纤。

import key from 'keymaster';
...
app.model({
  namespace: 'count',
  subscriptions: {
    keyEvent({dispatch}) {
      key('?+up, ctrl+up', () => { dispatch({type:'add'}) });
    },
  }
});

Router

這里的路由通常指的是前端路由,由于我們的應用現(xiàn)在通常是單頁應用纲缓,所以需要前端代碼來控制路由邏輯卷拘,通過瀏覽器提供的 History API 可以監(jiān)聽瀏覽器url的變化,從而控制路由相關操作祝高。

dva 實例提供了 router 方法來控制路由栗弟,使用的是react-router

import { Router, Route } from 'dva/router';
app.router(({history}) =>
  <Router history={history}>
    <Route path="/" component={HomePage} />
  </Router>
);

Route Components

組件設計方法中褂策,我們提到過 Container Components横腿,在 dva 中我們通常將其約束為 Route Components,因為在 dva 中我們通常以頁面維度來設計 Container Components斤寂。

所以在 dva 中耿焊,通常需要 connect Model的組件都是 Route Components,組織在/routes/目錄下遍搞,而/components/目錄下則是純組件(Presentational Components)罗侯。

DvaJS官網(wǎng)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市溪猿,隨后出現(xiàn)的幾起案子钩杰,更是在濱河造成了極大的恐慌,老刑警劉巖诊县,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讲弄,死亡現(xiàn)場離奇詭異,居然都是意外死亡依痊,警方通過查閱死者的電腦和手機避除,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瓶摆,你說我怎么就攤上這事凉逛。” “怎么了群井?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵状飞,是天一觀的道長。 經(jīng)常有香客問我书斜,道長诬辈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任菩佑,我火速辦了婚禮自晰,結果婚禮上,老公的妹妹穿的比我還像新娘稍坯。我一直安慰自己酬荞,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布瞧哟。 她就那樣靜靜地躺著混巧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勤揩。 梳的紋絲不亂的頭發(fā)上咧党,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音陨亡,去河邊找鬼傍衡。 笑死,一個胖子當著我的面吹牛负蠕,可吹牛的內(nèi)容都是我干的蛙埂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼遮糖,長吁一口氣:“原來是場噩夢啊……” “哼绣的!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起欲账,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤屡江,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赛不,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惩嘉,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年踢故,在試婚紗的時候發(fā)現(xiàn)自己被綠了文黎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奏路。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖臊诊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斜脂,我是刑警寧澤抓艳,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站帚戳,受9級特大地震影響玷或,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜片任,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一偏友、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧对供,春花似錦位他、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至京景,卻和暖如春窿冯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背确徙。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工醒串, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鄙皇。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓芜赌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親育苟。 傳聞我的和親對象是個殘疾皇子较鼓,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354