DVA框架學(xué)習(xí)-01

? ? ? ?新入職的公司使用dva框架材义,之前沒有接觸過颖对,所以一邊學(xué)習(xí)赏寇,一邊工作吉嫩。記一下DVA框架的幾個基本概念。

首先放一下DVA框架數(shù)據(jù)流向:

image

? ? ? ?數(shù)據(jù)的改變發(fā)生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉(zhuǎn)等)觸發(fā)的嗅定,當(dāng)此類行為會改變數(shù)據(jù)的時候可以通過dispatch發(fā)起一個action自娩,如果是同步的行為,會直接通過reducer改變state渠退,如果是異步的行為(副作用)會先觸發(fā)effects然后流向reducer忙迁,最終改變state(一般是從服務(wù)器獲取數(shù)據(jù),拿到數(shù)據(jù)后觸發(fā)effects)碎乃,然后通過connect(一個函數(shù)姊扔,綁定state到view)渲染組件。所以在DVA中梅誓,數(shù)據(jù)流非常清晰簡明恰梢,并且思路基本跟開源社區(qū)保持一致。

DVA的幾個概念

Models組成:namespace梗掰,state嵌言,reducer,effect及穗, subscription

{
  namespace: 'count',
  state: 0,
  reducers: {
    add(state) { return state + 1 },
  },
  effects: {
    *addAfter1Second(action, { call, put }) {
      yield call(delay, 1000);
      yield put({ type: 'add' });
    },
  }
},
subscription{
}

State

? ? ? ?表示該model當(dāng)前的狀態(tài)摧茴。數(shù)據(jù)保存在這里,直接決定了視圖層的輸出拥坛。
? ? ? ?State表示Model的狀態(tài)數(shù)據(jù)蓬蝶,通常表現(xiàn)為一個js對象(當(dāng)然可以是任何值)尘分;操作的時候每次都要當(dāng)做不可變數(shù)據(jù)(immutable data)來對待猜惋,保證每次都是全新對象,沒有引用關(guān)系培愁,這樣才能保證State的獨立性著摔,便于測試和追蹤變化。

state:{
  namespace:'businessApprove',
  nodeList:[],
  checkList:[]
}

? ? ? ?在DVA中定续,你可以通過DVA的實例屬性_store來看到頂部的state數(shù)據(jù)谍咆,但是通常很少用到:

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

Action

? ? ? ?一個對象禾锤,描述事件,可以是同步摹察,也可以是異步恩掷。
Action是一個普通js對象,他是改變State的唯一途徑供嚎。無論是從UI事件黄娘,網(wǎng)絡(luò)回調(diào),還是WebSocket等數(shù)據(jù)源說獲得的數(shù)據(jù)克滴,最終都會通過dispatch函數(shù)調(diào)用一個action逼争,從而改變對應(yīng)的數(shù)據(jù)。action必須帶有type屬性指明具體的行為劝赔,其他字段可以自定義誓焦。如果要發(fā)起一個action需要使用dispatch函數(shù),需要注意的是dispatch是在組件connect Models以后通過props傳入的着帽,通過connect將model中的元素作為props的方式傳遞給component杂伟。

dispatch({
   type:'changeData',
   payload:{
      list:[],
    }
})
export default connect()(BusinessApprove)

connect

????通過connect將module中的元素作為props的方式傳遞給component。

export default connect(({ businessApprove, loading }) => ({ businessApprove, loading }))(BusinessApprove)

dispatch函數(shù)

????dispatch函數(shù)是一個用于觸發(fā)action的函數(shù)仍翰,action是改變state的唯一途徑稿壁,但是他只是描述了一個行為,而dispatch可以看做是觸發(fā)這個行為的方式歉备,而reducer則是描述如何改變數(shù)據(jù)的傅是。
????在DVA中,connect Model的組件通過props可以訪問到dispatch蕾羊,可以調(diào)用Model中的reducer或者effects喧笔,常見的形式如:

   dispatch({
        type:`${namespace}/changeData`,
       //如果在model外調(diào)用,需要添加namespace龟再,(`${namespace}`)
        payload: {//需要傳遞的信息
          list: [],
        }
    })

reducer

type Reducer<S,A> = (state:S,action:A) =>S
????reducer更新數(shù)據(jù)书闸,Action處理器,處理同步動作利凑,用來算出最新的state浆劲。
????reducer函數(shù)接受兩個參數(shù):之前已經(jīng)累積運算的結(jié)果和當(dāng)前要被累積的值,返回的是一個新的累積結(jié)果哀澈。該函數(shù)把一個集合歸并成一個單值牌借。reducer的概念來自于函數(shù)式編程。在DVA中割按,reducer聚合累積的結(jié)果是當(dāng)前model的state對象膨报。通過action中傳入的值,與當(dāng)前reducer中的值進行運算,獲得新的值(也就是新的state)现柠。需要注意的是院领,reducer必須是純函數(shù),所以同樣的輸入必然得到同樣的輸出够吩,它們不應(yīng)該產(chǎn)生任何副作用比然。并且,每一次的計算都應(yīng)該使用immutable data周循,這種特性簡單理解就是每次操作都是返回一個全新的數(shù)據(jù)(獨立谈秫、純凈),所以重?zé)彷d和時間旅行這些功能才能使用鱼鼓。

  reducers: {
    changeData (state, { payload }) {
      return { ...state, ...payload }
    },
    ...
  }

effect

????請求數(shù)據(jù)拟烫,action處理器,處理異步動作迄本。底層引入了redux-saga做異步流程控制硕淑,采用了generator的相關(guān)概念。effect是一個generator函數(shù)嘉赎,內(nèi)部使用yeild關(guān)鍵字置媳,標(biāo)識每一步的操作(不管是異步或者同步)。
????effect被稱為副作用公条。在我們的應(yīng)用中拇囊,最常見的就是異步操作。它來自于函數(shù)編程的概念靶橱,之所以叫副作用是因為它使我們的函數(shù)變得不純寥袭,同樣的輸入不一定獲得同樣的輸出。DVA為了控制副作用的操作关霸,底層引入了redux-saga做異步流程控制传黄,由于采用了generator的相關(guān)概念,所以將異步轉(zhuǎn)成同步寫法队寇,從而將effect轉(zhuǎn)換為純函數(shù)膘掰。

effects: {
    // 查詢付款列表
    * query ({ payload = {} }, { call, put, select }) {
      const data = yield call(query, payload)//發(fā)起ajax請求 service內(nèi)的query異步函數(shù)
      // const { tableKey } = yield select(({ paymentApprove }) => paymentApprove)//獲取model中的state
      if (data.success) {
        yield put({//提交reducer更改state
          type: 'changeData',
          payload: {
            list: data.data.list,
          },
        })
      } else {
        message.error(data.message, 1)
      }
    },

call和put

????DVA提供多個effect函數(shù)內(nèi)部的處理函數(shù),比較常用的是call和put佳遣。
????call:執(zhí)行異步函數(shù)
????put:發(fā)出一個action识埋,調(diào)用給定的函數(shù),類似于dispatch
????select:從全局中取數(shù)據(jù)

const num = yield select(
    state => state.count.num
 );

subscription

????用于訂閱一個數(shù)據(jù)源零渐,然后根據(jù)條件dispatch需要的action窒舟。數(shù)據(jù)源可以是當(dāng)前的時間,服務(wù)器的websocket連接相恃,keyboard的輸入辜纲,geolocation變化,history路由變化等等拦耐。subscription中無法監(jiān)聽state中的數(shù)據(jù)變化耕腾。
????model分兩類,一是全局model杀糯,二是頁面model扫俺。全局model存在于/src/model/目錄,所有頁面都可以引用固翰,頁面model不能被其他頁面所引用狼纬。
????規(guī)則如下:

  • src/models/*/.js 為 global model
  • src/pages//models//*.js 為 page model
  • global model 全量載入,page model 在 production 時按需載入骂际,在 development 時全量載入
  • page model 為 page js 所在路徑下 models/*/.js 的文件
  • page model 會向上查找疗琉,比如 page js 為 pages/a/b.js,他的 page model 為 pages/a/b/models//.js + pages/a/models//.js歉铝,依次類推
  • 約定 model.js 為單文件 model盈简,解決只有一個 model 時不需要建 models 目錄的問題,有 model.js 則不去找 models/*/.js
    dva01-02.png

    如上目錄:
    ● global model 為 src/models/g.js
    ● /a 的 page model 為 src/pages/a/models/{a,b,ss/s}.js
    ● /c 的 page model 為 src/pages/c/model.js
    ● /c/d 的 page model 為 src/pages/c/model.js, src/pages/c/d/models/d.js
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末太示,一起剝皮案震驚了整個濱河市柠贤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌类缤,老刑警劉巖臼勉,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異餐弱,居然都是意外死亡宴霸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門膏蚓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猖败,“玉大人,你說我怎么就攤上這事降允《魑牛” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵剧董,是天一觀的道長幢尚。 經(jīng)常有香客問我,道長翅楼,這世上最難降的妖魔是什么尉剩? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮毅臊,結(jié)果婚禮上理茎,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好皂林,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布朗鸠。 她就那樣靜靜地躺著,像睡著了一般础倍。 火紅的嫁衣襯著肌膚如雪烛占。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天沟启,我揣著相機與錄音忆家,去河邊找鬼。 笑死德迹,一個胖子當(dāng)著我的面吹牛芽卿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胳搞,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蹬竖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了流酬?” 一聲冷哼從身側(cè)響起币厕,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芽腾,沒想到半個月后旦装,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡摊滔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年阴绢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艰躺。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡呻袭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腺兴,到底是詐尸還是另有隱情左电,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布页响,位于F島的核電站篓足,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏闰蚕。R本人自食惡果不足惜栈拖,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望没陡。 院中可真熱鬧涩哟,春花似錦索赏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锻弓,卻和暖如春砾赔,著一層夾襖步出監(jiān)牢的瞬間蝌箍,已是汗流浹背青灼。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留妓盲,地道東北人杂拨。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像悯衬,于是被迫代替她去往敵國和親弹沽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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