2、Redux與Fluxjavascript
Redux的三個基本原則css
A、惟一數據源(全局只有一個Store)html
B、保持狀態只讀(不能直接修改Store狀態)java
C、數據改變只能經過純函數完成react
一、Redux與Flux不一樣點npm
(1)Store保持惟一redux
(2) Store中的邏輯和保存的狀態值分離(邏輯在reducer中處理)api
二、Redux實踐(實現與Flux相同功能的效果)服務器
首先須要安裝「redux」 npm install --save redux函數
(1)Action(分兩個文件,一個ActionType.js,另外一個Actions.js)
ActionTypes.js(將常量單獨拿出)
Actions.js
Redux中每一個action構造函數都返回一個action對象(Flux中,是將action經過Dispatcher的實例調用dispatch函數派發出去)
注意:Redux中,沒有Dispatcher
(2)Store
這裏引入Redux庫所提供的createStore函數。最後返回一個保存了應用全部 state 的對象(即store對象)
注意:(i)Redux的Store狀態設計的主要原則就是「避免冗餘的數據」。由於Counter狀態數值相加就是Summary組件的狀態值,因此不須要在爲Summary單獨在Store進行數據存儲;
(ii)createStore的第二個參數可選,一般是服務器給出的,若是提供了這個參數,會覆蓋reducer函數的初始化state
(3)Reducer
說明:reducer函數中有兩個參數:
第一個參數爲state,這個state指初始化狀態值。若是createStore中,寫了第二個參數,即指定初始化狀態值,那麼這個state默認就是createStore中第二個參數的值,若是createStore中沒有指定第二個state初始化參數,則須要在reducer函數的參數中,爲state的設定默認值 (一般爲對象形式),不然在第一次建立存儲時,會報錯,以下
第二個參數爲action, reducer在接受這個派發過來的action以後,產生一個新的狀態值
其中:
return { ...state,[counterCaption]:state[counterCaption]+1 }
等同於
const newState = Object.assgin( { } , state ) ;
newState[counterCaption] ++ ;
return newState;
注意:(i)Reducer是一個純函數,不能直接對輸入值state進行修改。咱們採用的是拷貝出一個新的state,而後進行相應操做
(ii)在實際中調用了reducer兩次,一次是在建立存儲時(返回初始化state,此時沒action),而後在調度以後再次調用(返回與action對應的新state)。
(4)View (分3個組件,ControlPanel,Counter,Summary)
ControlPanel.js
Counter.js
說明:當點擊「+」時,會將對應的action對象派發出去
注意:在Flux中,action構造函數既負責創造對象,又負責派發(經過Dispatcher實例的dispatch方法)
在Redux中,action構造函數只負責建立對象(派發經過store.dispatch)
Summary.js
(5)最後理一下整個過程(仍是以點擊「+」按鈕爲例)
過程一:先按着組件生命週期函數順序進行初始化加載。並在componentDidMount()中,經過store.subscribe中放入onChange監聽器,監聽store狀態變化
過程二:當點擊「+」按鈕時
(以第一個Counter爲例)
拿取Counter上caption的屬性值,並傳入increment中,生成一個新的action,而後經過store.dispatch派發
過程三:在過程二中派發action,此時被reducer函數接收,並根據action對象中的動做類型做出相應的「加一」操做,最後返回一個新的state,固然了,這個過程是在createStore函數內部發生的,畢竟咱們只給createStore函數傳入的只是reducer這個函數名,最後createStore返回一個Store對象
過程四:store發生了變化了,被store.subscribe監聽到,經過store.getState拿到新的store,並將其渲染到頁面上
三、拓展:
createStore是redux中重中之重的知識點,我在網上找了一下createStore源碼,最後仍是選擇了阮一峯老師的簡單實現版,簡單實現版中getState,dispatch,subscribe和源碼思路差很少,爲了直觀,我把他整合在以前的demo中,方便理解
(此時將原先從「redux」庫中引入的createStore註釋了)
最後也能夠實現一樣效果
結合本身的demo,我也標記了一些本身的理解註釋
四、總結Redux流程
部分參考
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html