成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺談Flux架構(gòu)及Redux實(shí)踐

開發(fā) 架構(gòu)
Flux是Facebook用來構(gòu)建用戶端的Web應(yīng)用程序的體系架構(gòu),與其它形式化的框架相比,它更像是一個(gè)架構(gòu)思想,用于管理和控制應(yīng)用中數(shù)據(jù)的流向。這里應(yīng)用中的數(shù)據(jù)指包括但不限于來自服務(wù)端的數(shù)據(jù)頁面中view的一些狀態(tài)(如一個(gè)面板是展開還是關(guān)閉),臨時(shí)存儲(chǔ)在本地需要持久化到服務(wù)端的數(shù)據(jù)等。

Flux概述

Flux是Facebook用來構(gòu)建用戶端的Web應(yīng)用程序的體系架構(gòu),與其它形式化的框架相比,它更像是一個(gè)架構(gòu)思想,用于管理和控制應(yīng)用中數(shù)據(jù)的流向。這里應(yīng)用中的數(shù)據(jù)指包括但不限于來自服務(wù)端的數(shù)據(jù)頁面中view的一些狀態(tài)(如一個(gè)面板是展開還是關(guān)閉),臨時(shí)存儲(chǔ)在本地需要持久化到服務(wù)端的數(shù)據(jù)等。

好了,說了這么多好像還是一臉懵逼,不慌,接下來看看展開式。

 MVC

在講述Flux之前,我們看看之前傳統(tǒng)的MVC架構(gòu)以及在前端中的一些問題繼而思考Flux帶來的改變。MVC(Model-View-Controller)***興起于后端,通過對(duì)應(yīng)用程序復(fù)雜度的簡(jiǎn)化使程序更加直觀和便于維護(hù)。后端程序MVC中View可以看為數(shù)據(jù)的呈現(xiàn),Model為數(shù)據(jù)的模型,Controller作為程序的流程控制。現(xiàn)在假設(shè)有這樣的場(chǎng)景,用戶想查看自己的profile頁面,可能會(huì)有這樣的流程:在頁面上點(diǎn)擊profile按鈕,接下來就是一個(gè)HTTP請(qǐng)求(/profile?username=jiavan) => Controller接收到這一請(qǐng)求并獲得請(qǐng)求的內(nèi)容username=jiavan然后告知Model需要jiavan的數(shù)據(jù) => Model返回了jiavan的數(shù)據(jù) => Controller得到數(shù)據(jù)返回新的視圖,看下流程: 

 現(xiàn)在前端中又有這樣的場(chǎng)景:切換Menu中的Item,當(dāng)前選中的Item顏色不同于其它顏色并且底部顯示對(duì)應(yīng)Item的內(nèi)容。一般情況下我們會(huì)定義一個(gè)css class來作為當(dāng)前選中Item的樣式。當(dāng)用戶點(diǎn)擊Item_A為被點(diǎn)擊的元素新增高亮的class,其它兄弟元素移除該樣式,這里的事件響應(yīng)函數(shù)就是Controller,我們會(huì)在這里處理樣式修改邏輯,以及更新Model的數(shù)據(jù),然后新的數(shù)據(jù)及樣式重新渲染界面。這種VC<->M的形式在關(guān)系比較簡(jiǎn)單的情況下是比較清晰容易控制的,但是復(fù)雜的頁面上這樣的模式可能會(huì)變得非常混亂:

 之所以變得混亂了,因?yàn)楹芏鄓iew都具備修改多個(gè)model的能力,這里的單個(gè)修改行為可以稱之為一個(gè)Action,一個(gè)Action的產(chǎn)生可能是用戶行為,或者一個(gè)Ajax請(qǐng)求需要渲染新界面。對(duì)比上面后端傳統(tǒng)MVC模式可以發(fā)現(xiàn):

  • 后端中Action作為一個(gè)URL請(qǐng)求,前端中可能是一個(gè)事件;
  • 后端中Action處理被集中在Controller中,而前端中是分散的。

那么是不是可以把前端中修改狀態(tài)即state的行為(事件回調(diào)/Ajax)全部抽象成一種Action描述,然后交付到一處即Reducers來進(jìn)行原子化處理,然后Reducer修改整個(gè)應(yīng)用中唯一的一棵state tree即Store,***通過state->view的機(jī)制來重新渲染?

Flux數(shù)據(jù)流框架

上面提到的幾個(gè)概念已經(jīng)對(duì)Flux有了初步的了解,下面進(jìn)入正題。相信有了解Flux的都應(yīng)該看過下面這張著名的數(shù)據(jù)流圖:

 

  1. Action可以看成是修改Store的行為抽象;
  2. Dispatcher管理著應(yīng)用的數(shù)據(jù)流,可以看為Action到Store的分發(fā)器;
  3. Store管理著整個(gè)應(yīng)用的狀態(tài)和邏輯,類似MVC中的Model。

所以Flux可以被看作傳統(tǒng)MVC的改進(jìn)而非顛覆,當(dāng)我***次看到Flux的時(shí)候其實(shí)是比較懵逼,但看到并使用了Redux后確實(shí)有一種非常驚艷的感覺。

Redux

按照Redux官方的描述Redux is a predictable state container for JavaScript apps.,其中predictable和state container體現(xiàn)了它的作用。那么如何來理解可預(yù)測(cè)化的呢?這里會(huì)有一些函數(shù)式編程方面的思想,在Redux中reducer函數(shù)是一個(gè)純函數(shù),相同輸入一定會(huì)是一致的輸出,所以確定輸入的state那么reducer函數(shù)輸出的state一定是可以被預(yù)測(cè)的,因?yàn)樗粫?huì)進(jìn)行單純的計(jì)算,保證正確的輸出。狀態(tài)容器又是什么?說明Redux有一個(gè)專門管理state的地方,就是Store,并且一般情況下是唯一的,應(yīng)用中所有state形成的一顆狀態(tài)樹就是Store。Redux由Flux演變而來,但受 Elm 的啟發(fā),避開了 Flux 的復(fù)雜性,我們看看其數(shù)據(jù)流向:

 

 不同于Flux架構(gòu),Redux中沒有dispatcher這個(gè)概念,并且Redux設(shè)想你永遠(yuǎn)不會(huì)變動(dòng)你的數(shù)據(jù),你應(yīng)該在reducer中返回新的對(duì)象來作為應(yīng)用的新狀態(tài)。但是它們都可以用(state, action) => newState來表述其核心思想,所以Redux可以被看成是Flux思想的一種實(shí)現(xiàn),但是在細(xì)節(jié)上會(huì)有一些差異。

重要概念

  1. 應(yīng)用中的所有state都以一個(gè)object tree的形式存儲(chǔ)在一個(gè)單一的store中;
  2. 唯一能改store的方法是觸發(fā)action,action是動(dòng)作行為的抽象;
  3. 為了描述action如何改變state樹,需要編寫reducer函數(shù)。

這里需要說明一點(diǎn)的是reducer函數(shù),它應(yīng)當(dāng)是一個(gè)純函數(shù),不應(yīng)該有副作用,不應(yīng)有API調(diào)用,Date.now()或者隨機(jī)獲取等不穩(wěn)定的操作,應(yīng)當(dāng)保證相同的輸入reducer計(jì)算的結(jié)果應(yīng)該是一致的輸出,它只會(huì)進(jìn)行單純的計(jì)算。編寫reducer函數(shù)也是Redux中比較重要的一塊,它的形式如下:

  1. function testReducer(state, action) { 
  2.   switch (action.type) { 
  3.     case ACTION_TYPE: 
  4.       // calc... 
  5.       return newState; 
  6.     defaultreturn state; 
  7.   } 
  8.   return newState; 
  9.  

state是不可修改的,所以返回的新state應(yīng)該是基于輸入state副本的修改,而不是直接修改state后的返回。

原則

1. 單一數(shù)據(jù)源,store

整個(gè)應(yīng)用的state被存放在一棵Object tree中,并且這個(gè)Object tree只存在唯一一個(gè)store中;

2. state是只讀的

唯一能改變state的方法是觸發(fā)action,action是對(duì)已經(jīng)發(fā)生了的事情的抽象描述,簡(jiǎn)單的講,它把行為抽象成了一個(gè)對(duì)象。

比如,刪除一條記錄的action可以抽象的理解為:

  1.   type: 'DELETE_ITEM'
  2.   index: 1, 
  3.  

3. 使用純函數(shù)來實(shí)現(xiàn)state歸并操作,reducer

傳入待修改的state和一個(gè)告知reducer如何修改state的action,reducer將返回action規(guī)則對(duì)應(yīng)下操作后的新的state。

reducer(state, action) => new state

數(shù)據(jù)流

嚴(yán)格的單向數(shù)據(jù)流是Redux設(shè)計(jì)的核心

Redux應(yīng)用數(shù)據(jù)的生命周期遵循下面4個(gè)步驟:

  1. 調(diào)用store.dispatch(action), 可以在任何地方進(jìn)行;
  2. Redux store調(diào)用傳入的reducer函數(shù),并且將當(dāng)前的state樹與action傳入。reducer是純函數(shù),只用于計(jì)算下一個(gè)state,它應(yīng)該是完全可被預(yù)測(cè)的,相同的輸入必定會(huì)有相同的輸出,不能有副作用的操作,如API的調(diào)用或者路由跳轉(zhuǎn),這些應(yīng)該都是在dispatch前產(chǎn)生;
  3. 根reducer將多個(gè)子reducer輸出合并成一個(gè)單一的state樹;
  4. Redux store保存了根reducer返回的完整的state樹。
    新的state樹就是應(yīng)用的下一個(gè)狀態(tài),現(xiàn)在就可以根據(jù)新的state tree來渲染UI。

Redux實(shí)踐

我們通過一個(gè)非常簡(jiǎn)單的計(jì)數(shù)器demo來梳理Redux的數(shù)據(jù)流。

0x00. 創(chuàng)建action

action其實(shí)就是一個(gè)普通的對(duì)象,只是對(duì)行為的抽象描述,這里我們可以把加上一個(gè)數(shù)描述為:

  1.   type: INCREMENT, //該動(dòng)作的抽象描述 
  2.   number, // 該動(dòng)作攜帶的數(shù)據(jù) 
  3.  

更多的時(shí)候我們會(huì)通過一個(gè)action生成函數(shù)來得到一個(gè)action:

  1. function incrementCreator(number) { 
  2.   return { 
  3.     type: INCREMENT, 
  4.     number, 
  5.   }; 
  6.  

0x01. 創(chuàng)建reducer函數(shù)

reducer作為整個(gè)Redux中action的處理中樞,接收state與action并對(duì)此修改數(shù)據(jù),返回應(yīng)用的下一個(gè)狀態(tài)。

  1. function countReducer(state, action) { 
  2.   switch (action.type) { 
  3.     case INCREMENT: 
  4.       return Object.assign({}, { 
  5.         counter: state.counter + action.number, 
  6.       }); 
  7.     case DECREMENT: 
  8.       return Object.assign({}, { 
  9.         counter: state.counter - action.number, 
  10.       }); 
  11.     defaultreturn state; 
  12.   } 
  13.  

注意:上面我們已經(jīng)提到多次,state是不可修改的,所以通過assign歸并我們對(duì)數(shù)據(jù)的操作,返回的是state副本修改后的對(duì)象,并非直接修改了輸入的state。

0x02. 創(chuàng)建唯一store

通過Redux中的createStore方法傳入reducer函數(shù)來創(chuàng)建整個(gè)應(yīng)用的store。

  1. const store = createStore(countReducer); 

0x03. 修改state

通過store的dispatch方法來發(fā)起一個(gè)action。

  1. store.dispatch(incrementCreator(5)); 
  2.  
  3. store.dispatch(decrementCreator(4));  

完整demo 

  1. import { createStore } from 'redux'
  2.  
  3. // actions 
  4. const INCREMENT = 'INCREMENT'
  5. const DECREMENT = 'DECREMENT'
  6.  
  7. // actionCreator,可以視為創(chuàng)建action的語法糖 
  8. function incrementCreator(number) { 
  9.   return { 
  10.     type: INCREMENT, 
  11.     number, 
  12.   }; 
  13.  
  14. function decrementCreator(number) { 
  15.   return { 
  16.     type: DECREMENT, 
  17.     number, 
  18.   }; 
  19.  
  20. // 初始化state 
  21. const initialState = { 
  22.   counter: 0, 
  23. }; 
  24.  
  25. // reducers函數(shù),注意***一定要return state防止不能匹配到action的時(shí)候state丟失 
  26. function countReducer(state = initialState, action) { 
  27.   switch (action.type) { 
  28.     case INCREMENT: 
  29.       return Object.assign({}, { 
  30.         counter: state.counter + action.number, 
  31.       }); 
  32.     case DECREMENT: 
  33.       return Object.assign({}, { 
  34.         counter: state.counter - action.number, 
  35.       }); 
  36.     defaultreturn state; 
  37.   } 
  38.  
  39. // 創(chuàng)建store 
  40. const store = createStore(countReducer); 
  41.  
  42. // 訂閱store的修改 
  43. const unsubscribe = store.subscribe(function log() { 
  44.   console.log(store.getState()); 
  45. }); 
  46.  
  47. // 通過dispatch action來改變state 
  48. store.dispatch(incrementCreator(5)); //Object {counter: 5} 
  49. store.dispatch(decrementCreator(4)); //Object {counter: 1} 
  50.  
  51. // 取消訂閱 
  52. unsubscribe();  

 

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2015-08-26 09:27:32

Facebook架構(gòu)

2011-04-15 14:37:45

JavaCsv

2011-04-02 09:30:46

JavaIO

2017-11-10 13:02:44

iOSUI代碼

2021-08-05 07:28:25

虛擬化超融合架構(gòu)

2021-03-30 08:50:26

零信任架構(gòu)零信任網(wǎng)絡(luò)威脅

2016-12-19 11:17:48

架構(gòu) MVC

2019-10-11 10:52:42

Web架構(gòu)MongoDB

2023-06-12 15:43:44

鴻蒙智能家居開發(fā)

2009-08-20 09:41:36

2021-12-15 10:05:25

軟件開發(fā) 技術(shù)

2009-07-05 11:23:44

2023-12-17 14:36:05

2021-03-22 11:49:19

架構(gòu)運(yùn)維技術(shù)

2018-08-29 13:57:40

前端性能測(cè)試Html5

2018-09-11 09:33:49

Redis高可用架構(gòu)

2011-08-18 12:19:17

vSwitchVMNIC

2015-08-18 08:55:03

redux核心

2009-07-01 13:54:03

JSP注釋

2019-04-03 10:28:04

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美成年人视频在线观看 | 亚洲欧美一区二区三区在线 | 国产精品久久国产精品久久 | 免费国产一区 | 久久av一区二区三区 | 69视频在线播放 | 国产一区在线免费 | 日韩三级免费网站 | 欧美综合一区二区 | 日韩一区二区福利 | 秋霞在线一区 | 男女羞羞在线观看 | 黄色国产在线视频 | 中文字幕日本一区二区 | 亚州视频在线 | 成人精品鲁一区一区二区 | 狠狠爱综合 | 日韩成人免费在线视频 | 免费观看av网站 | 亚洲国产精品久久久久 | 九九热精品免费 | 久久精品亚洲成在人线av网址 | www.亚洲视频 | av电影手机在线看 | 久久久视 | 日本午夜免费福利视频 | 欧美日韩一卡二卡 | av中文字幕在线观看 | av喷水| 日韩一区二区三区视频在线观看 | 久久成人18免费网站 | 久草网免费 | 999精品视频| 欧美成人hd | 不卡的av在线 | 国产乱码精品一区二区三区中文 | 91亚洲精品国偷拍自产在线观看 | 五月婷婷激情网 | 国产精品成av人在线视午夜片 | 国产精品色婷婷久久58 | 精品一区二区三区在线观看 |