關(guān)于dva框架的一些基本概念

在介紹基本概念之前,我想先梳理一下dva框架里面的數(shù)據(jù)流向,這個(gè)十分重要绽昼。多話不說,先上圖:


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

數(shù)據(jù)的改變發(fā)生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉(zhuǎn)等)觸發(fā)的须蜗,當(dāng)此類行為會(huì)改變數(shù)據(jù)的時(shí)候可以通過dispatch發(fā)起一個(gè) action硅确,如果是同步行為會(huì)直接通過Reducers改變State,如果是異步行為(副作用)會(huì)先觸發(fā)Effects然后流向Reducers最終改變State明肮,所以在 dva 中菱农,數(shù)據(jù)流向非常清晰簡明,并且思路基本跟開源社區(qū)保持一致(也是來自于開源社區(qū))柿估。

下面我們再來看看相關(guān)的重要概念循未,看概念的時(shí)候一定要聯(lián)系上面的圖片,腦中要清晰它的數(shù)據(jù)流向:

State

type State = any

State 表示 Model 的狀態(tài)數(shù)據(jù)秫舌,通常表現(xiàn)為一個(gè) javascript 對象(當(dāng)然它可以是任何值)的妖;操作的時(shí)候每次都要當(dāng)作不可變數(shù)據(jù)(immutable data)來對待,保證每次都是全新對象足陨,沒有引用關(guān)系羔味,這樣才能保證 State 的獨(dú)立性,便于測試和追蹤變化钠右。

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

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

reducers

以 key/value 格式定義 reducer忘蟹。用于處理同步操作飒房,唯一可以修改state的地方。由action觸發(fā)媚值。

格式為(state, action) => newState或[(state, action) => newState, enhancer]狠毯。

詳見:https://github.com/dvajs/dva/blob/master/test/reducers-test.js

Action

type AsyncAction = any

Action 是一個(gè)普通 javascript 對象,它是改變 State 的唯一途徑褥芒。無論是從 UI 事件嚼松、網(wǎng)絡(luò)回調(diào)嫡良,還是 WebSocket 等數(shù)據(jù)源所獲得的數(shù)據(jù),最終都會(huì)通過 dispatch 函數(shù)調(diào)用一個(gè) action献酗,從而改變對應(yīng)的數(shù)據(jù)寝受。action 必須帶有type屬性指明具體的行為,其它字段可以自定義罕偎,如果要發(fā)起一個(gè) action 需要使用dispatch函數(shù)很澄;需要注意的是dispatch是在組件 connect Models以后,通過 props 傳入的颜及。

dispatch({

????????type: 'add',

});

dispatch 函數(shù)

type dispatch = (a: Action) => Action

dispatching function 是一個(gè)用于觸發(fā) action 的函數(shù)甩苛,action 是改變 State 的唯一途徑,但是它只描述了一個(gè)行為俏站,而 dipatch 可以看作是觸發(fā)這個(gè)行為的方式讯蒲,而 Reducer 則是描述如何改變數(shù)據(jù)的。

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

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

Reducer

type Reducer = (state: S, action: A) => S

Reducer(也稱為 reducing function)函數(shù)接受兩個(gè)參數(shù):之前已經(jīng)累積運(yùn)算的結(jié)果和當(dāng)前要被累積的值萌丈,返回的是一個(gè)新的累積結(jié)果。該函數(shù)把一個(gè)集合歸并成一個(gè)單值雷则。

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

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

在 dva 中月劈,reducers 聚合積累的結(jié)果是當(dāng)前 model 的 state 對象度迂。通過 actions 中傳入的值,與當(dāng)前 reducers 中的值進(jìn)行運(yùn)算獲得新的值(也就是新的 state)猜揪。需要注意的是 Reducer 必須是純函數(shù)惭墓,所以同樣的輸入必然得到同樣的輸出,它們不應(yīng)該產(chǎn)生任何副作用而姐。并且腊凶,每一次的計(jì)算都應(yīng)該使用immutable data,這種特性簡單理解就是每次操作都是返回一個(gè)全新的數(shù)據(jù)(獨(dú)立拴念,純凈)钧萍,所以熱重載和時(shí)間旅行這些功能才能夠使用。

Effect

Effect 被稱為副作用政鼠,在我們的應(yīng)用中风瘦,最常見的就是異步操作。它來自于函數(shù)編程的概念公般,之所以叫副作用是因?yàn)樗沟梦覀兊暮瘮?shù)變得不純万搔,同樣的輸入不一定獲得同樣的輸出胡桨。

dva 為了控制副作用的操作,底層引入了redux-sagas做異步流程控制瞬雹,由于采用了generator的相關(guān)概念 昧谊,所以將異步轉(zhuǎn)成同步寫法,從而將effects轉(zhuǎn)為純函數(shù)挖炬。至于為什么我們這么糾結(jié)于純函數(shù)揽浙,如果你想了解更多可以閱讀Mostly adequate guide to FP,或者它的中文譯本JS函數(shù)式編程指南意敛。

Subscription

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

Subscription 語義是訂閱草姻,用于訂閱一個(gè)數(shù)據(jù)源钓猬,然后根據(jù)條件 dispatch 需要的 action。數(shù)據(jù)源可以是當(dāng)前的時(shí)間撩独、服務(wù)器的 websocket 連接敞曹、keyboard 輸入、geolocation 變化综膀、history 路由變化等等澳迫。

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

Router

這里的路由通常指的是前端路由,由于我們的應(yīng)用現(xiàn)在通常是單頁應(yīng)用剧劝,所以需要前端代碼來控制路由邏輯橄登,通過瀏覽器提供的History API可以監(jiān)聽瀏覽器url的變化,從而控制路由相關(guān)操作讥此。

dva 實(shí)例提供了 router 方法來控制路由拢锹,使用的是react-router

import{Router,Route}from'dva/router';app.router(({history})=>);

Route Components

組件設(shè)計(jì)方法中萄喳,我們提到過 Container Components卒稳,在 dva 中我們通常將其約束為 Route Components,因?yàn)樵?dva 中我們通常以頁面維度來設(shè)計(jì) Container Components他巨。

所以在 dva 中充坑,通常需要 connect Model的組件都是 Route Components,組織在/routes/目錄下染突,而/components/目錄下則是純組件(Presentational Components)匪傍。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市觉痛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茵休,老刑警劉巖薪棒,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件手蝎,死亡現(xiàn)場離奇詭異,居然都是意外死亡俐芯,警方通過查閱死者的電腦和手機(jī)棵介,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吧史,“玉大人邮辽,你說我怎么就攤上這事∶秤” “怎么了吨述?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钞脂。 經(jīng)常有香客問我揣云,道長,這世上最難降的妖魔是什么冰啃? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任邓夕,我火速辦了婚禮,結(jié)果婚禮上阎毅,老公的妹妹穿的比我還像新娘焚刚。我一直安慰自己,他們只是感情好扇调,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布矿咕。 她就那樣靜靜地躺著,像睡著了一般肃拜。 火紅的嫁衣襯著肌膚如雪痴腌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天燃领,我揣著相機(jī)與錄音士聪,去河邊找鬼。 笑死猛蔽,一個(gè)胖子當(dāng)著我的面吹牛剥悟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播曼库,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼区岗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了毁枯?” 一聲冷哼從身側(cè)響起慈缔,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎种玛,沒想到半個(gè)月后藐鹤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓤檐,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年娱节,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挠蛉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肄满,死狀恐怖谴古,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稠歉,我是刑警寧澤掰担,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站轧抗,受9級特大地震影響恩敌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜横媚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一纠炮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧灯蝴,春花似錦恢口、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至问潭,卻和暖如春猿诸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狡忙。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工梳虽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人灾茁。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓窜觉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親北专。 傳聞我的和親對象是個(gè)殘疾皇子禀挫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容