上篇文章庖丁解牛React-Redux(一): connectAdvanced介紹了react-redux的Provider
、connectAdvanced
幾個重要API的原理,其中connectAdvanced
是connect
函數的基礎,這篇文章將主要介紹connect
函數的原理。以前沒有閱讀過connectAdvanced
最好提早閱讀一下這篇文章。以前的文章有讀者反映看起來比較晦澀,因此我準備隨後會出一篇關於相似圖解connectAdvanced
的文章,不講代碼,主要從原理的方面詮釋connectAdvanced
。再次作個廣告,歡迎你們關注個人掘金帳號和個人博客。javascript
最開始咱們仍是來介紹一下connect
函數:
java
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
將React組件鏈接到Redux store,connect
函數是connectAdvanced
的正面,爲大多數常見場景提供了易於使用的API。connect
函數並不會修改傳遞的組件,相反,它會返回一個新的,鏈接到store
的組件類。react
參數:git
[mapStateToProps(state, [ownProps]): stateProps](Function):
若是這個參數被傳遞,返回新的組件將會訂閱Redux的store的更新(update)。這意味着任什麼時候刻store
更新,mapStateToProps
將會被調用。mapStateToProps
必須返回一個純對象(plain object),這個對象將會合並進組件的屬性(props)。若是你不想訂閱store的更新,能夠給mapStateToProps
參數傳遞null
或者undefined
。github
若是你的mapStateToProps
函數被聲明接受兩個參數,mapStateToProps
在調用時第一個參數是store state
,傳遞給鏈接組件(connected component)的屬性將會被做爲第二個參數。若是鏈接組件接受到新的props(淺比較),mapStateToProps
也會再次調用。redux
注意: 在一些更高級的狀況下,你須要更好的控制渲染的性能,
mapStateToProps
能夠返回一個函數。這種場景下,返回的函數將會被做爲特定組件實例的mapStateProps()
函數。這容許你能夠對每一個實例緩存。但大部分應用用不到。數組
mapStateToProps
函數接受一個參數: Redux中store的state,並返回一個對象做爲屬性返回給被包裹的組件。這一般被稱爲`selector。緩存
mapDispatchToProps(dispatch, [ownProps]): dispatchProps:性能優化
若是傳入參數是一個對象,對象中的每一個函數都被認爲是Redux的action creator函數。返回的對象中的每一個action creator函數都會被dispatch
所包裹,所以能夠直接調用,最終會被合併進入組件的屬性。閉包
若是傳遞一個函數,該函數的第一個參數爲dispatch
。須要你返回一個對象,其中的屬性以你的方式將dispatch
與action creator相綁定。
若是你的mapDispatchToProps
函數聲明接受兩個參數,第一個函數是dispatch
,第二個參數是傳遞給鏈接組件的屬性。每當鏈接組件收到新的參數時,mapDispatchToProps
就會被再次調用。
若是沒有傳入自定義的mapDispatchToProps
函數或者對象,默認的mapDispatchToProps
將爲你的組件注入dispatch
屬性。
注意:
mapDispatchToProps
也能夠返回函數,用法與mapStateToProps
相同
mergeProps(stateProps, dispatchProps, ownProps): props:
若是指定了這個參數,傳入的參數爲:函數 mapStateToProps()
、mapDispatchToProps()
的運行結果以及傳入鏈接組件的屬性。從該函數返回的對象將會被當作屬性傳遞給被包裹的組件。你可能會指定這個函數來基於props來選擇性傳入state,或者按照傳入props綁定action creator。若是你省略了這個函數,默認是實現方式是:`
Object.assign({}, ownProps, stateProps, dispatchProps)
`
options
若是你指定了這個選項,更進一步自定義connector的行爲。除了能夠傳入connectAdvanced
的選項,還能夠接受額外的選項:
[pure] (Boolean): 若是參數爲true,用來避免從新渲染並調用mapStateToProps
、mapDispatchToProps
和mergeProps
時基於各自的等值比較函數來比較所涉及到的state
和props
對象。
[areStatesEqual] (Function): 若是參數pure
爲true
,用來比較傳入的store與以前的store值。默認值: strictEqual (===)。
[areOwnPropsEqual] (Function):若是參數pure
爲true
,用來比較傳入的props與以前的props值。默認值: strictEqual (===)。
[areStatePropsEqual] (Function):若是參數pure
爲true
,用以比較mapStateToProps
函數的結果與以前的結果值。
[areMergedPropsEqual] (Function): 若是參數pure
爲true
,比較mergeProps
函數的結果與以前的值。默認值爲:shallowEqual。
[storeKey] (String): 用以從context獲取store的key值。你僅僅可能在有多個store值的狀況下才須要這個選項,默認值爲:store
。
connect
的代碼以下:
export function createConnect({ connectHOC = connectAdvanced, mapStateToPropsFactories = defaultMapStateToPropsFactories, mapDispatchToPropsFactories = defaultMapDispatchToPropsFactories, mergePropsFactories = defaultMergePropsFactories, selectorFactory = defaultSelectorFactory } = {}) { return function connect( mapStateToProps, mapDispatchToProps, mergeProps, { pure = true, areStatesEqual = strictEqual, areOwnPropsEqual = shallowEqual, areStatePropsEqual = shallowEqual, areMergedPropsEqual = shallowEqual, ...extraOptions } = {} ) { const initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories, 'mapStateToProps') const initMapDispatchToProps = match(mapDispatchToProps, mapDispatchToPropsFactories, 'mapDispatchToProps') const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps') return connectHOC(selectorFactory, { methodName: 'connect', getDisplayName: name => `Connect(${name})`, shouldHandleStateChanges: Boolean(mapStateToProps), initMapStateToProps, initMapDispatchToProps, initMergeProps, pure, areStatesEqual, areOwnPropsEqual, areStatePropsEqual, areMergedPropsEqual, ...extraOptions }) } } const connect = createConnect();
createConnect
做爲高階函數,返回connect
函數,經過柯里化的方式首先接受如下參數: connectHOC
、mapStateToPropsFactories
、mapDispatchToPropsFactories
、mergePropsFactories
與selectorFactory
。
傳入用來生成鏈接到store的高階組件(HOC),默認是以前介紹過的connectAdvanced
。
selectorFactory
用來生成selector
,第一個參數將傳入connectAdvanced
。咱們知道傳入connectAdvanced
的selectorFactory
函數主要是初始化selector函數。selector函數在每次connector component須要計算新的props都會被調用,selector函數會返回純對象(plain object),這個對象會做爲props傳遞給被包裹的組件(WrappedComponent)。selectorFactory
的函數簽名爲:
selectorFactory(dispatch, factoryOptions): selector(state, ownProps): props (Function)
咱們來看看redux
的selectorFactory
是怎麼定義的:
const selectorFactory = finalPropsSelectorFactory(dispatch, { initMapStateToProps, initMapDispatchToProps, initMergeProps, ...options }) { const mapStateToProps = initMapStateToProps(dispatch, options) const mapDispatchToProps = initMapDispatchToProps(dispatch, options) const mergeProps = initMergeProps(dispatch, options) if (process.env.NODE_ENV !== 'production') { verifySubselectors(mapStateToProps, mapDispatchToProps, mergeProps, options.displayName) } const selectorFactory = options.pure ? pureFinalPropsSelectorFactory : impureFinalPropsSelectorFactory return selectorFactory( mapStateToProps, mapDispatchToProps, mergeProps, dispatch, options ) }
selectorFactory
函數首先接受兩個參數,dispatch
和一系列的factoryOptions
,經過一系列的初始化函數分別生成了mapStateToProps
、mapDispatchToProps
、mergeProps
(初始化函數隨後會詳細介紹)。而後會在非生產環境下對上述三個函數進行驗證(驗證主要涉及到該函數是否爲空和函數中是否有dependsOnOwnProps屬性,這個屬性隨後會介紹的)。隨後即是函數的重點部分,根據options.pure
是否爲true,選擇恰當的selectorFactory
,而後返回selectorFactory(...args)
。
當options.pure
爲false
時,selectorFactory
的值爲:impureFinalPropsSelectorFactory
:
function impureFinalPropsSelectorFactory( mapStateToProps, mapDispatchToProps, mergeProps, dispatch ) { return function impureFinalPropsSelector(state, ownProps) { return mergeProps( mapStateToProps(state, ownProps), mapDispatchToProps(dispatch, ownProps), ownProps ) } }
咱們知道,selectorFactory
會返回selector
函數,返回的函數會接受兩個參數:state
與ownProps
並最終返回屬性傳遞給被包裹的組件。咱們發現impureFinalPropsSelectorFactory
很是的簡單,只是單純的將要求的參數傳遞給mapStateToProps
,mapDispatchToProps
,並將其結果連同ownProps
一塊兒傳遞給mergeProps
,並將最後mergeProps
的結果做爲selector
函數的結果。這個結果最終會傳遞給被包裹組件,這個函數沒有什麼難度並且很是符合connect
函數的API。
但咱們知道在默認狀況下,options.pure
爲true
。所以selectorFactory
的值爲:pureFinalPropsSelectorFactory
:
pureFinalPropsSelectorFactory( mapStateToProps, mapDispatchToProps, mergeProps, dispatch, { areStatesEqual, areOwnPropsEqual, areStatePropsEqual } ) { let hasRunAtLeastOnce = false let state let ownProps let stateProps let dispatchProps let mergedProps // ...... return function pureFinalPropsSelector(nextState, nextOwnProps) { return hasRunAtLeastOnce ? handleSubsequentCalls(nextState, nextOwnProps) : handleFirstCall(nextState, nextOwnProps) } }
函數pureFinalPropsSelectorFactory
中有一個閉包變量hasRunAtLeastOnce
用來判斷是不是第一次調用,若是selector
函數是第一次調用,selector
會返回handleFirstCall(nextState, nextOwnProps)
不然返回handleSubsequentCalls(nextState, nextOwnProps)
。
function handleFirstCall(firstState, firstOwnProps) { state = firstState ownProps = firstOwnProps stateProps = mapStateToProps(state, ownProps) dispatchProps = mapDispatchToProps(dispatch, ownProps) mergedProps = mergeProps(stateProps, dispatchProps, ownProps) hasRunAtLeastOnce = true return mergedProps }
handleFirstCall
與以前的impureFinalPropsSelector
相比,只是作了緩存,保存了state
、ownProps
以及mapStateToProps
、dispatchProps
和mergedProps
的結果值。
function handleSubsequentCalls(nextState, nextOwnProps) { const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps) const stateChanged = !areStatesEqual(nextState, state) state = nextState ownProps = nextOwnProps if (propsChanged && stateChanged) return handleNewPropsAndNewState() if (propsChanged) return handleNewProps() if (stateChanged) return handleNewState() return mergedProps }
再看函數handleSubsequentCalls
。其中areOwnPropsEqual
、areStatesEqual
分別用來判斷props和state如今的值與緩存的值是否相等函數。handleSubsequentCalls
首先判斷state、props的先後值是否有變化,而後緩存了state
、ownProps
。若是props和state都發送改變了,返回handleNewPropsAndNewState
的結果,若是props
改變了,返回handleNewProps
的運行結果。若是state
改變,返回handleNewState
運行結果,不然若是state
和props
都沒發生改變,說明都沒有發生改變。直接返回以前緩存的mergedProps
的值。
handleNewPropsAndNewState
定義以下:
function handleNewPropsAndNewState() { stateProps = mapStateToProps(state, ownProps) if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps) mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps }
咱們看到,若是props和state都發送改變了,調用了handleNewPropsAndNewState
,首先就是運行mapStateToProps
返回stateProps
的值並緩存,其次咱們會根據mapDispatchToProps.dependsOnOwnProps
的值去判別是否運行mapDispatchToProps
。dependsOnOwnProps
的值主要是用來判別mapDispatchToProps
是否依賴於ownProps的值。最終執行mergeProps
函數,緩存結果並傳入被包裹的組件。
function handleNewProps() { if (mapStateToProps.dependsOnOwnProps) stateProps = mapStateToProps(state, ownProps) if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps) mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps }
理解了handleNewPropsAndNewState
,handleNewProps
將會很是簡單,分別去判別state
與dispatchProps
是否與ownProps相關。以判別是否須要從新運行mapStateToProps
和mapDispatchToProps
。最終將mergeProps
運行的值緩存並傳遞給被包裹的組件。
function handleNewState() { const nextStateProps = mapStateToProps(state, ownProps) const statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps) stateProps = nextStateProps if (statePropsChanged) mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps }
handleNewState
用來生成新的state。根據是否state
變化,選擇性是否執行mergeProps
,最終返回mergedProps
給被包裹組件。
到如今爲止,其實咱們已經知道了selectorFactory
是與pure
值掛鉤的。若是pure
爲true
的話,selectorFactory
返回的selector
會對state
和props
等值都會緩存,而後會根據具體的場景,儘量使得傳入被包裹組件的值改動最少(即儘量返回相同的值),其目的就是減小沒必要要的渲染。當pure
爲false
值,不會作任何的緩存。
看完了selectorFactory
,咱們須要去了解一下mapStateToProps
是怎麼來的:
//connect.js // initMapStateToProps會被傳入 selectorFactory const initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories, 'mapStateToProps')
//selectorFactory.js const mapStateToProps = initMapStateToProps(dispatch, options) //mapStateToProps的使用(注意這裏的mapStateToProps不是傳入的函數,而是init函數生成的函數): const stateProps = mapStateToProps(state, ownProps)
咱們能夠看到,首先在connect.js
中經過match
函數取生成initMapStateToProps
。而後在selectorFactory
中,生成了mapStateToProps
的函數,而後會在selector
函數中使用mapStateToProps
生成了stateProps
,最後將stateProps
傳遞給被包裹的組件。
首先看match
函數的定義:
function match(arg, factories, name) { for (let i = factories.length - 1; i >= 0; i--) { const result = factories[i](arg) if (result) return result } return (dispatch, options) => { throw new Error(`Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`) } }
接下來的內容相對來講會比較複雜,咱們先提早梳理一下match
函數的運做,其中factories
是一個數組,它的實參將會是相似於mapStateToPropsFactories
(數組)等值,而後args
將是你自定義的mapStateToProps
函數等值(好比mapStateToDispatch
)。咱們將會以args
做爲參數從後到前執行factories
數組中的每個函數,找到第一個返回不爲假(相似於undefined
)的函數而且咱們能夠保證這個函數返回的是另外一個函數,其簽名相似於:
(dispatch,options)=>{ //.... return ()=>{ } }
這個返回的函數接受dispatch
和其餘選項options
做爲參數,最終返回一個函數供selector
使用的函數 ,好比mapStateToPropsFactories
必定會返回一個相似與於下面的函數:
(state, ownProps) =>{ //...... //return plain object }
這個函數將用來計算新的state傳遞給被包裹的組件。
對於mapStateToProps
的來源要追溯到:
const initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories, 'mapStateToProps')
在函數match
中第一個實參是你傳入connect
的mapStateToProps
。第二個實參mapStateToPropsFactories
的定義以下:
const mapStateToPropsFactories = [ whenMapStateToPropsIsFunction, whenMapStateToPropsIsMissing ]; function whenMapStateToPropsIsFunction(mapStateToProps) { return (typeof mapStateToProps === 'function') ? wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps') : undefined } function whenMapStateToPropsIsMissing(mapStateToProps) { return (!mapStateToProps) ? wrapMapToPropsConstant(() => ({})) : undefined }
上面的代碼都不難,首先判斷傳入的mapStateToProps
是否是相似於null
,若是是執行whenMapStateToPropsIsMissing
不然去執行whenMapStateToPropsIsFunction
。對於whenMapStateToPropsIsMissing
來講,重要的是whenMapStateToPropsIsMissing
的定義:
function wrapMapToPropsConstant(getConstant) { return function initConstantSelector(dispatch, options) { const constant = getConstant(dispatch, options) function constantSelector() { return constant } constantSelector.dependsOnOwnProps = false return constantSelector } }
wrapMapToPropsConstant
函數接受的參數是一個函數,這個函數負責在selector
返回一個常量做爲props返回給被包裹組件。由於返回的老是一個常量,因此dependsOnOwnProps
爲false
,表示返回給被包裹組件的值與鏈接到store的高階組件接受到的props
無關。
那麼whenMapStateToPropsIsMissing
函數調用wrapMapToPropsConstant
的參數是一個空函數(()=>{}
),那就說明在mapStateToProps
值爲空(null
)的時候,是不給被包裹組件傳遞任何的屬性的。
whenMapStateToPropsIsFunction
的狀況會比較複雜,若是傳入的mapStateToProps
是一個函數,那麼就會調用wrapMapToPropsFunc
:
function wrapMapToPropsFunc(mapToProps, methodName) { return function initProxySelector(dispatch, { displayName }) { const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) { return proxy.dependsOnOwnProps ? proxy.mapToProps(stateOrDispatch, ownProps) : proxy.mapToProps(stateOrDispatch) } proxy.dependsOnOwnProps = true proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) { proxy.mapToProps = mapToProps proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps) let props = proxy(stateOrDispatch, ownProps) if (typeof props === 'function') { proxy.mapToProps = props proxy.dependsOnOwnProps = getDependsOnOwnProps(props) props = proxy(stateOrDispatch, ownProps) } if (process.env.NODE_ENV !== 'production') verifyPlainObject(props, displayName, methodName) return props } return proxy } }
wrapMapToPropsFunc
的函數相對來講比較複雜,接受的參數是你傳入的mapStateToProps
函數(methodName
的做用只是錯誤提示),返回的是初始化selector
函數(initProxySelector
)。當使用initProxySelector
初始化selector
的時候,返回的函數proxy
實則爲一個代理(proxy
)。第一次執行proxy
(selector
)時,dependsOnOwnProps
的值爲true
,因此至關於執行proxy.mapToProps(stateOrDispatch, ownProps)
(detectFactoryAndVerify
),而後將proxy.mapToProps
屬性設置爲你所傳入的mapStateToProps
函數。這時候再去執行getDependsOnOwnProps
的目的是去肯定你傳入的mapStateToProps
是否須要傳入props
。而後再去執行proxy(stateOrDispatch, ownProps)
,這時候proxy.mapToProps
已經不是以前的detectFactoryAndVerify
而是你傳入的mapStateToProps
(因此不會出現死循環)。執行的結果就是mapStateToProps
運行後的結果。若是prop
是對象,將會直接傳遞給被包裹組件。可是咱們以前講過,mapStateToProps
是能夠返回一個函數的,若是返回的值爲一個函數,這個函數將會被做爲proxy
的mapStateToProps
,再次去執行proxy
。
再去了解一下mapStateToProps
的來源:
//connect.js const initMapDispatchToProps = match(mapDispatchToProps, mapDispatchToPropsFactories, 'mapDispatchToProps')
//selectFactory const mapDispatchToProps = initMapDispatchToProps(dispatch, options) //使用: const dispatchProps = mapDispatchToProps(dispatch, ownProps)
其實mapDispatchToProps
是和mapStateToProps
的來源很是類似,照理看mapDispatchToPropsFactories
:
const mapDispatchToPropsFactories = [ whenMapDispatchToPropsIsFunction, whenMapDispatchToPropsIsMissing, whenMapDispatchToPropsIsObject ] function whenMapDispatchToPropsIsFunction(mapDispatchToProps) { return (typeof mapDispatchToProps === 'function') ? wrapMapToPropsFunc(mapDispatchToProps, 'mapDispatchToProps') : undefined } function whenMapDispatchToPropsIsMissing(mapDispatchToProps) { return (!mapDispatchToProps) ? wrapMapToPropsConstant(dispatch => ({ dispatch })) : undefined } function whenMapDispatchToPropsIsObject(mapDispatchToProps) { return (mapDispatchToProps && typeof mapDispatchToProps === 'object') ? wrapMapToPropsConstant(dispatch => bindActionCreators(mapDispatchToProps, dispatch)) : undefined }
若是你已經看懂了wrapMapToPropsConstant
和wrapMapToPropsFunc
的函數的話,mapDispatchToPropsFactories
也就不難了。若是傳入的mapStateToProps
的值是一個對象的話,會調用whenMapDispatchToPropsIsObject
。繼而調用了wrapMapToPropsConstant
並傳入的參數是函數:dispatch => bindActionCreators(mapDispatchToProps, dispatch)
。根據咱們以前經驗,那麼傳遞給被包裹的組件的屬性將是:bindActionCreators(mapDispatchToProps, dispatch)
的運行結果,即被dispatch
包裹的action
。
若是沒有傳入mapDispatchToProps
函數的話,調用whenMapDispatchToPropsIsMissing
。傳入函數wrapMapToPropsConstant
的參數爲:dispatch => ({ dispatch })
,那麼被包裹的組件接受的參數便是store
的dispatch
方法。
若是傳入的mapDispatchToProps
是一個函數,調用whenMapDispatchToPropsIsFunction
函數。從而調用wrapMapToPropsFunc(mapDispatchToProps, 'mapDispatchToProps')
。運行的原理與運行wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps')
基本相同,能夠參照以前。
//connect.js const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps')
//selectorFactory const mergeProps = initMergeProps(dispatch, options) //使用 mergedProps = mergeProps(stateProps, dispatchProps, ownProps)
仍是先看一下mergePropsFactories
是怎麼定義的:
const mergePropsFactories = [ whenMergePropsIsFunction, whenMergePropsIsOmitted ] function whenMergePropsIsFunction(mergeProps) { return (typeof mergeProps === 'function') ? wrapMergePropsFunc(mergeProps) : undefined } function whenMergePropsIsOmitted(mergeProps) { return (!mergeProps) ? () => defaultMergeProps : undefined }
若是你沒有傳入mapStateToProps
函數,那麼調用函數whenMergePropsIsOmitted()
。到最後margedProps
函數便是defaultMergeProps
,defaultMergeProps
的定義爲:
function defaultMergeProps(stateProps, dispatchProps, ownProps) { return { ...ownProps, ...stateProps, ...dispatchProps } }
若是你傳入了mapStateToProps
函數,調用函數whenMergePropsIsFunction()
,調用了wrapMergePropsFunc(mergeProps)
,其中參數mergeProps
便是你所傳入的mergeProps
:
function wrapMergePropsFunc(mergeProps) { return function initMergePropsProxy(dispatch, { displayName, pure, areMergedPropsEqual }) { let hasRunOnce = false let mergedProps return function mergePropsProxy(stateProps, dispatchProps, ownProps) { const nextMergedProps = mergeProps(stateProps, dispatchProps, ownProps) if (hasRunOnce) { if (!pure || !areMergedPropsEqual(nextMergedProps, mergedProps)) mergedProps = nextMergedProps } else { hasRunOnce = true mergedProps = nextMergedProps if (process.env.NODE_ENV !== 'production') verifyPlainObject(mergedProps, displayName, 'mergeProps') } return mergedProps } } }
wrapMergePropsFunc
中涉及到性能優化,首先wrapMergePropsFunc
返回一個初始mergeProps
的函數(mergePropsProxy
)。函數mergePropsProxy
閉包一個變量hasRunOnce
來記錄mergeProps
運行次數,在mergeProps
第一次運行時,會保存第一次傳入被包裹組件的的props
,再之後的運行過程當中,若是你傳入的參數pure
爲true
而且先後的mergedProps
值不一樣時(比較函數你能夠自定義)纔會傳入新的屬性,不然將傳入以前的緩存值,以此來優化沒必要要的渲染。
到此爲止,咱們基本已經在代碼層面講完了connect
函數的原理,文章很長,有的地方可能相對比較難理解,建議你們均可以去從總體上看看react-redux
的源碼。react-redux
源碼解讀系列接下來會以其餘的角度去分析react-redux
,歡迎你們繼續關注。