第三章 從Flux到Redux(Redux篇)

3.2 Redux

?????????這本書的主題是關(guān)于Redux的毯侦,所以我們不要停留在Flux上太久毡熏。終于砖茸,我們要開始接觸Redux了。

? ? ????我們把Flux看作一個框架理念的話碉碉,Redux是Flux的一種實現(xiàn)柴钻,除了Redux之外,還有很多實現(xiàn)Flux的框架垢粮,比如Reflux贴届、Fluxible等,毫無疑問Redux獲得的關(guān)注最多,這不是偶然的粱腻,因為Redux有很多框架無法比擬的優(yōu)勢庇配。

3.2.1 Redux的基本原則

? ? ? ? 2013年問世的Flux飽受爭議,而2015年Dan Abramov提出了在Flux基礎(chǔ)上的改進框架Redux绍些,則是一鳴驚人捞慌,在所有Flux的變體中算是最受關(guān)注的框架,沒有之一柬批。

? ? ? ? Flux的基本原則是“單項數(shù)據(jù)流”啸澡,Redux在此基礎(chǔ)上強調(diào)三個基本原則:

? ? ? ? ? 唯一數(shù)據(jù)源(Single Source of Truth)

? ? ? ? ? 保持狀態(tài)只讀(State is read-only)

? ? ? ? ? 數(shù)據(jù)改變只能通過純函數(shù)完成(Changes are with pure functions)

? ? ? ? 讓我們逐一介紹這三種基本原則。

????? ? 1.唯一數(shù)據(jù)源

? ? ? ? 唯一數(shù)據(jù)源指的是應用的狀態(tài)數(shù)據(jù)應該只存儲在唯一的一個Store中氮帐。

? ? ? ? 我們已經(jīng)知道嗅虏,在Flux中,應用可以擁有多個Store上沐,往往根據(jù)功能把應用的狀態(tài)數(shù)據(jù)劃分給若干個Store分別存儲管理皮服。比如,在上面的CounterPanel例子中参咙,我們創(chuàng)造了CounterStore和SummaryStore龄广。

? ? ? ? 如果狀態(tài)數(shù)據(jù)分散在多個Store中,容易造成數(shù)據(jù)冗余蕴侧,這樣數(shù)據(jù)一致性方面就會出問題择同。雖然利用Dispatch的waitFor方法可以保證多個Store之間的更新順序,但是這又產(chǎn)生了不同Store之間的顯示依賴關(guān)系净宵,這種依賴關(guān)系的存在增加了應用的復雜度敲才,容易帶來新的問題。

????????Redux對這個問題的解決方法就是择葡,整個應用只保持一個Store紧武,所有組件的數(shù)據(jù)源就是這個Store上的狀態(tài)。

注意:Redux并沒有阻止一個應用擁有多個Store刁岸。只是脏里,在Redux的框架下,糖一個應用用于多個Store不會帶來任何好處虹曙,最后還不如使用一個Store更容易組織代碼迫横。

? ? ????這個唯Store上的狀態(tài),是一個樹形的對象酝碳,每個組件往往只是樹形對象上一部分的數(shù)據(jù)矾踱,而如何設計Store上狀態(tài)的結(jié)構(gòu),就是Redux應用的核心問題疏哗,我們接下來會描述具體細節(jié)呛讲。

2.保持狀態(tài)可讀

? ? ? ? 保持狀態(tài)可讀,就是說不能去修改狀態(tài),要修改Store的狀態(tài)贝搁,必須通過派發(fā)一個action對象完成吗氏,這一點,和Flux并沒有什么區(qū)別雷逆。

? ? ? ? 如果只看這個原則的字面意思弦讽,可能會讓讀者感覺有點費解,還記得那個公式嗎膀哲?UI=render(state)往产,我們已經(jīng)說過驅(qū)動用戶界面更改的是狀態(tài),如果狀態(tài)都是只讀的不能修改某宪,怎么可能引起用戶界面的變化呢仿村?

·? ? ? ? 當然,要驅(qū)動用戶界面渲染兴喂,就要改變應用的狀態(tài)蔼囊,但是改變狀態(tài)的方法不是去修改狀態(tài)上的值,而是創(chuàng)建一個新的狀態(tài)對象返回給Redux瞻想,由Redux完成新的狀態(tài)的組裝压真。

? ? ? ? 這就直接引出了下面的第三個基本原則。

3.數(shù)據(jù)改變只能通過純函數(shù)完成

? ? ? ? 這里所說的純函數(shù)就是Reducer蘑险,Redux這個名字的前三個字母Red代碼的就是Reducer。按照創(chuàng)作者Dan Abramov的說法岳悟,Redux名字的含義是Reducer+Flux佃迄。

? ? ? ? Reducer不是一個Redux特定的術(shù)語,而是一個計算機科學的通過概念贵少,很多語言和框架都有對Reducer函數(shù)的支持呵俏。就以JavaScript為例,數(shù)組類型就有reduce函數(shù)滔灶,接受的參數(shù)就是一個reducer普碎,reduce做的事情就是把數(shù)組所有元素依次做“規(guī)約”,對每個元素都調(diào)用一次參數(shù)reducer录平,通過reducer函數(shù)完成規(guī)約所有元素的功能麻车。

? ? ? ? 下面是一個使用reducer函數(shù)的例子:

? ? ? ? [1,2,3,4].reduce(function reducer(accumulation,item){

????????return accumulation+item

????},0);

? ? ? ? 上面的代碼中,reducer(注意不是reduce)函數(shù)接受兩個參數(shù)斗这,第一個參數(shù)是上一次規(guī)約的結(jié)果动猬,第二個參數(shù)是這一次規(guī)約的元素,函數(shù)體是返回兩者之和表箭,所以這個規(guī)約的結(jié)果就是所有元素之和赁咙。

? ? ? ? 在Redux中,每個reducer的函數(shù)簽名如下所示:

? ? ? ? reducer(state,action)

? ? ? ? 第一個參數(shù)state是當前的狀態(tài),第二個參數(shù)action是接受到的action對象彼水,而reducer函數(shù)要做的事情崔拥,就是根據(jù)state和action的值產(chǎn)生一個新的對象返回,注意reducer必須是純函數(shù)凤覆,也就是說函數(shù)的返回結(jié)果必須完全由參數(shù)state和action決定握童,而且不產(chǎn)生任何副作用,也不能修改參數(shù)state和action對象叛赚。

? ? ? ? 讓我們回顧一下Flux中的Store是如何處理函數(shù)的澡绩,代碼如下:

? ? ? ? CounterStore.dispatchToken = AppDispatcher.register((action)=>{

? ? ? ? ? ? if(action.type ===ActionType.INCREMENT){

? ? ? ? ? ? counterValues[action.counterCaption]++;

? ? ? ? ? ? CounterStore.emitChange();

????????}else if(action.type ===ActionTypes.DECREMENT){

? ????????counterValues[action.counterCaption]--;

? ? ? ? ? ? CounterStore.emitChange();

????????}

????});

? ? ? ? Flux更新狀態(tài)的函數(shù)只有一個參數(shù)action,因為狀態(tài)是由Store直接管理的俺附,所以處理函數(shù)中會看到代碼直接更新state肥卡;在Redux中,一個實現(xiàn)同樣功能的reducer代碼如下:

? ? ? ? function reduce(state,action)=>{

????????const {counterCaption} = action;

? ? ? ? siwtch(action.type){

? ? ? ? ? ? case ActionTypes.INCREMENT:

? ? ? ? ? ? return {...state,[counterCaption]:state[counterCaption]+1};

????????case ActionTypes.DECREMENT:

? ? ? ? ? ? return {...state,[counterCaption]:state[counterCaption]-1};

????????}

????}

????????可以看到reducer函數(shù)不光接受action為參數(shù)事镣,還接受state為參數(shù)步鉴。也就是說,Redux的reducer只負責計算狀態(tài)璃哟,卻并不負責存儲狀態(tài)氛琢。

? ? ? ? 我們會在后面的實例中詳細解釋這個reducer的構(gòu)造。

? ? ? ? 讀到這里随闪,讀者可能會有一個疑問阳似,從Redux的基本原則來看,Redux并沒有賦予我們更強大的功能铐伴,反而是給開發(fā)者增加了很多限制啊撮奏,開發(fā)者喪失了想怎么寫就怎么寫的靈活度。而:增加限制卻正是提高軟件質(zhì)量的法門当宴。

3.2.2 Redux實例

? ? ? ? 單純只看書面介紹難以理解Redux如何工作的畜吊,讓我們還是通過例子來介紹。

? ? ? ? 前面我們用Flux實現(xiàn)了一個ControlPanel的應用户矢,接下來讓我們用Redux來重新實現(xiàn)一遍同樣的功能玲献,通過對比查看二者的差異。

? ? ? ? React和Redux事實上是兩個獨立的產(chǎn)品梯浪,一個應用可以使用React而不使用Redux捌年,也可以使用Redux而不使用React,但是驱证,如果兩者結(jié)合使用延窜,沒有理由不使用一個名叫react-redux的庫,這個庫能夠大大簡化代碼的書寫抹锄。

? ? ? ? 不過逆瑞,如果一開始就使用react-redux荠藤,可能對其設計思路一頭霧水,所以获高,我們的實例先不采用react-redux庫哈肖,而從最簡單的Redux使用方法開始,初步改進念秧,循序漸進地過渡到使用react-redux淤井。

? ? ? ? 最基本的Redux實現(xiàn),存在于本書對于Github的chapter-03/redux_basic目錄中摊趾,在這里我們只關(guān)注使用Redux實現(xiàn)和使用Flux實現(xiàn)的不同的文件币狠。

未完待續(xù)。



? ??????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砾层,一起剝皮案震驚了整個濱河市漩绵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肛炮,老刑警劉巖止吐,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侨糟,居然都是意外死亡碍扔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門秕重,熙熙樓的掌柜王于貴愁眉苦臉地迎上來不同,“玉大人,你說我怎么就攤上這事悲幅√锥欤” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵汰具,是天一觀的道長。 經(jīng)常有香客問我菱魔,道長留荔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任澜倦,我火速辦了婚禮聚蝶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藻治。我一直安慰自己碘勉,他們只是感情好,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布桩卵。 她就那樣靜靜地躺著验靡,像睡著了一般倍宾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胜嗓,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天高职,我揣著相機與錄音,去河邊找鬼辞州。 笑死怔锌,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的变过。 我是一名探鬼主播埃元,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼媚狰!你這毒婦竟也來了岛杀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤哈雏,失蹤者是張志新(化名)和其女友劉穎楞件,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裳瘪,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡土浸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了彭羹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黄伊。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖派殷,靈堂內(nèi)的尸體忽然破棺而出还最,到底是詐尸還是另有隱情,我是刑警寧澤毡惜,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布拓轻,位于F島的核電站,受9級特大地震影響经伙,放射性物質(zhì)發(fā)生泄漏扶叉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一帕膜、第九天 我趴在偏房一處隱蔽的房頂上張望枣氧。 院中可真熱鬧,春花似錦垮刹、人聲如沸达吞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酪劫。三九已至吞鸭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間契耿,已是汗流浹背瞒大。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搪桂,地道東北人透敌。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像踢械,于是被迫代替她去往敵國和親酗电。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

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