根據源碼分析react-redux本質
02-09
Provider,Connect組件實質上是一個利用高階函數的方式將React Component作為參數的包裝組件(或者說是抽象包裝組件)1.Provider.jsreact-redux中的Provider其實就是react context(蟲洞) 的一個實現.如圖: 1-1
1-2
根據以上的代碼,可以實現整個react組件樹可以共享一個store,從而可以擺脫繁瑣的通過props做父子組件間的通訊.2.connect.js如圖:2-1connect函數參數第一個參數:mapStateToProps(state,ownProps):Object,該方法接收兩個參數,state(表示store.getState()返回的數據)和ownProps(表示在組件調用時傳遞的props),在Connect組件的render()方法里作為mergeProps()方法的第一個參數.第二個參數:mapDispatchToProps(state,ownProps):Object,該方法接收兩個參數,dispatch(表示store.dispatch)和ownProps(表示在組件調用時傳遞的props),在Connect組件的render()方法里作為mergeProps()方法的第二個參數.
第三個參數:mergeProps(stateProps,dispatchProps,parentProps):Object,該方法接收三個參數,stateProps(表示mapStateToProps方法返回的對象字面量),dispatchProps(表示mapDispatchToProps方法返回的對象字面量),parentProps(表示在組件調用時傳遞的props),在Connect組件的render()方法里將stateProps,dispatchProps,parentProps合併並返回最新的對象字面量,最終作為包裝組件的props.如圖:2-2下圖中的代碼在Connect組件的render()方法中connect方法回返回一個wrapWithConnect(WrappedComponent):wrapComponent,該方法用於給需要包裝的React Component進行包裝,並返回包裝好的Component.wrapWithConnect方法中定義了許多方法.比如:1.computeMergedProps(合併屬性)2.Connect.prototype.computeStateProps(計算stateProps)
3.Connect.prototype.configureFinalMapState(解析並返回符合要求的stateProps)4.Connect.prototype.computeDispatchProps(計算dispatchProps)5.Connect.prototype.configureFinalMapDispatch(解析並返回符合要求的dispatchProps)6.Connect.prototype.updateStatePropsIfNeeded(是否需要更新stateProps)7.Connect.prototype.updateDispatchPropsIfNeeded(是否需要更新dispatchProps)8.Connect.prototype.updateMergedPropsIfNeeded(是否需要更新mergeProps)9.Connect.prototype.isSubscribed(是否已有store監聽)10.Connect.prototype.trySubscribe(綁定store監聽,該方法在store.dispatch()方法執行後被觸發)11.Connect.prototype.tryUnsubscribe(解除對store的監聽)12.Connect.prototype.clearCache(清除數據緩存)
13.Connect.prototype.handleChange(判斷是否需要更新store數據,如果需要更新,在該方法最後會執行Connect組件的this.setState(),trySubscribe方法中會調用該方法)14.Connect.prototype.render(在Connect組件調用this.setState()方法後觸發該方法,該方法會執行上述許多代碼,並且判斷數據是否需要更新,最終合併成mergedProps後將該作為包裝組件的props使用)上述列舉了很多方法都是不會在應用層直接調用的,主要執行流程如下:使用connect方法包裝目標組件->Connect組件內部註冊store.subscribe監聽->執行store.dispatch()->觸發Connect組件註冊的監聽->handleChange()方法執行Connect組件的this.setState()->觸發Connect組件render()方法->判斷stateProps,dispatchProps,mergeProps是否需要更新,並將mergeProps作為包裝組件的props,使用React.createElement()方法創建的包裝組件作為Connect組件的render()方法的返回值->最新的store傳遞到包裝組件中.根據以上流程描述,connect包裝的組件在每次執行store.dispatch()後,都會觸發包裝組件的重繪,並傳遞最新的store,其原理即是使用store.subscribe()方法監聽store.dispatch()方法的執行,隨後觸發Connect組件的this.setState()方法,觸發render()方法判斷store是否更新並用React.createElement()方法重新創建包裝組件並使用mergedProps作為props,隨後再把創建好的包裝組件作為Connect組件render()方法的返回值.完成以上過程後,包裝組件即可獲得最新的store數據.
推薦閱讀:
※react配合redux的生命周期(shouldComponentUpdate)的問題?
※redux中所有state都要放在store里嗎?
※Redux狀態管理之痛點、分析與改良
※Redux store 的動態注入