React原理及其工作流程
react-redux提供了connect和provider兩個好方式,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-redux讓它們聯絡在一起。
redux由store,reducer,action組成
store是一個物件,它主要有四個方法
dispatch:用於action的分發,在creactStore中對dispatch進行改造,比如當action傳入dispatch中會立即觸發reducer,有時我們不希望立即觸發,而是等待非同步操作結束後觸發,這時不是隻能傳入一個物件,而是能傳入一個函式,在函式裡我們dispatch一個action物件,實現了非同步
subscribe:監聽state的變化,這個函式呼叫dispatch時會註冊一個listener監聽state變化當我們需要知道state是否變化時可以呼叫,它返回一個函式,呼叫這個返回的函式可以登出監聽,let unsubscribe=store.subscribe(()=>{console.log("state發生了變化")})
getState: 兩個需要用到的地方: 1.獲取store中的state,用action觸發reducer改變了state時,並將資料傳給reducer這個過程是自動執行的 2.利用subscribe監聽到state發生變化後呼叫它來獲取新的state資料
replaceReducer: 替換reducer,改變state修改的邏輯
store通過createStore()方法建立,接受三個引數,經過combineReducers合併的reducer和state初始狀態以及改變dispatch的中介軟體,後兩個引數不是必須的,store的主要作用是將action和reducer聯絡起來並改變state,
action
action是一個物件,其中type屬性是必須的,同時可以傳入一些資料,action可以用actionCreator進行創造,dispatch就是把action物件傳送出去
reducer
reducer是一個函式,它接受一個state和一個action,根據action的type返回一個新的state根據業務邏輯可以分為多個reducer,然後通過combineReducers將它們合併,state中有很多物件,每個state物件對應一個reducer, eg: const reducer =combineReducers( { a:doSomethingWithA, b:processB, c:c } )
combineReducers:
其實它也是一個reducer,它接受整個state和一個action,然後將整個state拆分發送給對應的reducer進行處理,所有的reducer會收到相同的action,不過他們會根據action的type進行判斷,有這個就進行處理然後返回新的state,沒有就返回預設值,然後分散的state又會整合在一起返回一個新的state,
connect
connect(mapStateToProps,mapDispatchToProps,mergeProps,options)是一個函式,它接受 四個引數並且再返回一個函式,wrapWithConnect,wrapWithConnect接受一個元件作為引數,它的內部定義一個新元件,並將傳入的元件作為Connect的子元件然後return回去。
完整寫法: connect(mapStateToProps,mapDispatchToProps,mergeProps,options)(component)
mapStateToProps(state,[ownProps])
1.mapStateToProps接受兩個引數,store的state和自定義的props, 2.並返回一個新的物件,這個物件會作為props的一部分傳入ui元件, 3.我們可以根據元件所需要的資料自定義返回一個物件,ownProps的變化也會觸發mapStateProps function mapStateToProps(state){ return {todos:state.todos}; }
mapDispatchToProps(dispatch,[ownProps])
1.mapDispatchToProps如果是物件,那麼會和store繫結作為props的一部分傳入ui元件 2.如果是個函式,它接受兩個引數,bindActionCreators會將action和dispatch繫結並返回一個物件,這個物件會和ownProps一起作為props的一部分傳入ui元件, 3.所以不論mapDispatchToProps是物件還是函式,它最終都會返回一個物件,如果是函式,這個物件的key值是可以自定義的。 4.mapDispatchToProps返回的物件屬性其實就是一個個actionCeator,因為已經和dispatch繫結,所以當呼叫actionCreator時會立即傳送action,而不是手動dispatch, 5.ownProps的變化也會觸發mapDispatchToProps
mergeProps(tateProps,dispatchProps,ownProps)
將 mapStateToProps()和mapDispatchToProps()返回的物件和元件自身的props合併成新的props並傳入元件,預設返回stateProps和dispatchProps的結果之和
options:
pure=true表示Connect容器元件將在shouldComponentUpdate中對store的state和ownProps進行淺對比,判斷是否發生變化,優化效能,為false則不對比。
完整的React--Redux--React流程
一.Provider元件接受redux的store作為props,然後通過context往下傳
二.connect 函式在初始化的時候會將mapDispatchToProps 物件繫結到store,
如果mapDispatchToProps 是函式則在Connect 元件獲得store 之後,
根據傳入的store.dispatch 和action 通過bindActionCreators進行繫結,再將返回的物件繫結到store ,connect 函式會返回一個wrapWithConnect 函式,
同時wrapWithConnect 會被呼叫且傳入一個ui元件 ,wrapWithConnect 內部定義了一個Connect 元件,傳入的ui元件是Connect的子元件 ,
然後Connect 元件會通過context獲得store,並通過store.getState 獲得完整的state物件,將state傳入mapStateToProps 返回stateProps物件,
然後Connect元件會通過context獲得store,並通過store.getState 獲得完整的state物件,將state傳入mapStateToProps 返回stateProps 物件、mapDispatchToProps 物件或mapDispatchToProps 函式會返回一個dispatchProps 物件,stateProps 、dispatchProps 以及Connect 元件的props
三.
此時ui元件就可以在props中找到actionCreator,
當我們呼叫actionCreator時會自動呼叫dispatch,
在dispatch中會呼叫getState獲取整個state,同時註冊一個listener監聽state的變化,
store將獲得的state和action傳給combineReducers,
combineReducers會將state依據state的key值分別傳給子reducer,並將action傳給全部子reducer,
reducer會被依次執行進行action.type的判斷,如果有則返回一個新的state,如果沒有則返回預設。
combineReducers再次將子reducer返回的單個state進行合併成一個新的完整的state。此時state發生了變化。
dispatch在state返回新的值之後會呼叫所有註冊的listener函式其中包括handleChange函式,
handleChange函式內部首先呼叫getState獲取新的state值並對新舊兩個state進行淺對比,如果相同直接return,
如果不同則呼叫mapStateToProps獲取stateProps並將新舊兩個stateProps進行淺對比,如果相同,直接return結束,不進行後續操作。
如果不相同則呼叫this.setState()觸發Connect元件的更新,傳入ui元件,觸發ui元件的更新,此時ui元件獲得新的props,
react --> redux --> react 的一次流程結束。