首先,redux并不是必須的,它的作用相當于在頂層元件之上又加了一個元件,作用是進行邏輯運算、儲存資料和實作元件尤其是頂層元件的通信。如果元件之間的交流不多,邏輯不複雜,隻是單純的進行視圖的渲染,這時候用回調,context就行,沒必要用redux,用了反而影響開發速度。但是如果元件交流特别頻繁,邏輯很複雜,那redux的優勢就特别明顯了。我第一次做react項目的時候并沒有用redux,所有的邏輯都是在元件内部實作,當時為了實作一個邏輯比較複雜的購物車,洋洋灑灑居然寫了800多行代碼,回頭一看我自己都不知道寫的是啥,畫面太感人。
先簡單說一下redux和react是怎麼配合的。react-redux提供了connect和Provider兩個好基友,它們一個将元件與redux關聯起來,一個将store傳給元件。元件通過dispatch發出action,store根據action的type屬性調用對應的reducer并傳入state和這個action,reducer對state進行處理并傳回一個新的state放入store,connect監聽到store發生變化,調用setState更新元件,此時元件的props也就跟着變化。
流程是這個樣子的:

值得注意的是connect,Provider,mapStateToProps,mapDispatchToProps是react-redux提供的,redux本身和react沒有半毛錢關系,它隻是資料進行中心,沒有和react産生任何耦合,是react-redux讓它們聯系在一起。
接下來具體分析一下,redux以及react-redux到底是怎麼實作的。
先上一張圖
明顯比第一張要複雜,其實兩張圖說的是同一件事。從上而下慢慢分析:
先說說redux:
redux主要由三部分組成:store,reducer,action。
store是一個對象,它有四個主要的方法:
1、dispatch:
用于action的分發——在createStore中可以用middleware中間件對dispatch進行改造,比如當action傳入dispatch會立即觸發reducer,有些時候我們不希望它立即觸發,而是等待異步操作完成之後再觸發,這時候用redux-thunk對dispatch進行改造,以前隻能傳入一個對象,改造完成後可以傳入一個函數,在這個函數裡我們手動dispatch一個action對象,這個過程是可控的,就實作了異步。
2、subscribe:
監聽state的變化——這個函數在store調用dispatch時會注冊一個listener監聽state變化,當我們需要知道state是否變化時可以調用,它傳回一個函數,調用這個傳回的函數可以登出監聽。
let unsubscribe = store.subscribe(() => {console.log('state發生了變化')})
3、getState:
擷取store中的state——當我們用action觸發reducer改變了state時,需要再拿到新的state裡的資料,畢竟資料才是我們想要的。getState主要在兩個地方需要用到,一是在dispatch拿到action後store需要用它來擷取state裡的資料,并把這個資料傳給reducer,這個過程是自動執行的,二是在我們利用subscribe監聽到state發生變化後調用它來擷取新的state資料,如果做到這一步,說明我們已經成功了。
4、replaceReducer:
替換reducer,改變state修改的邏輯。
store可以通過createStore()方法建立,接受三個參數,經過combineReducers合并的reducer和state的初始狀态以及改變dispatch的中間件,後兩個參數并不是必須的。store的主要作用是将action和reducer聯系起來并改變state。
action是一個對象,其中type屬性是必須的,同時可以傳入一些資料。action可以用actionCreactor進行創造。dispatch就是把action對象發送出去。
reducer是一個函數,它接受一個state和一個action,根據action的type傳回一個新的state。根據業務邏輯可以分為很多個reducer,然後通過combineReducers将它們合并,state樹中有很多對象,每個state對象對應一個reducer,state對象的名字可以在合并時定義。
像這個樣子:
const reducer = combineReducers({
a: doSomethingWithA,
b: processB,
c: c
})