筆記----深入淺出《React和Redux》第三章Redux框架(不使用react-redux庫)
二、Redux與Flux
Redux的三個基本原則
A、唯一資料來源(全域性只有一個Store)
B、保持狀態只讀(不能直接修改Store狀態)
C、資料改變只能通過純函式完成()
1、Redux與Flux不同點
(1)Store保持唯一
(2) Store中的邏輯和儲存的狀態值分離(邏輯在reducer中處理)
2、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物件中的動作型別作出相應的加一操作,最後返回一個新的物件,當然了,這個過程是在createStore內部發生的,畢竟我們只給createStore函式傳入的只是reducer這個函式名
拓展:
createStore是redux中重中之重的知識點,
部分參考
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
https://css-tricks.com/learning-react-redux/