摘要:負責記錄所有的狀態(tài),以便在部分狀態(tài)發(fā)生改變,而不影響組件渲染的時候,可以避免不必要的渲染。作用是,每次或發(fā)生改變以后,調(diào)用這個返回的,獲取更新后的最終。由于發(fā)生改變,并不一定會造成返回結(jié)果的改變,所以需要根據(jù)檢查后的結(jié)果來判定是否調(diào)用方法。
注:這篇文章只是講解React Redux這一層,并不包含Redux部分。Redux有計劃去學習,等以后學習了Redux源碼以后再做分析
注:代碼基于現(xiàn)在(2016.12.29)React Redux的最新版本(5.0.1)
Connect工具類篇(1)
Connect工具類篇(2) verifySubselectors.js這里有四個參數(shù):
mapStateToProps, mapDispatchToProps, mergeProps都是經(jīng)過mapDispatchToProps, mapStateToProps, mergeProps封裝過的
displayName是option里面?zhèn)魅氲?br>主要做的是檢查傳入的mapStateToProps,mapDispatchToProps,mergeProps是否存在,由于這里的對象是經(jīng)過幾個map方法封裝過的,所以不存在就說明開發(fā)傳入的值是錯誤的。同時檢查是否有dependsOnOwnProps這個屬性,如果沒有給一個warning.
import warning from "../utils/warning" function verify(selector, methodName, displayName) { if (!selector) { throw new Error(`Unexpected value for ${methodName} in ${displayName}.`) } else if (methodName === "mapStateToProps" || methodName === "mapDispatchToProps") { //只檢查mapStateToProps和mapDispatchToProps, 因為mergeProps方法不需要 if (!selector.hasOwnProperty("dependsOnOwnProps")) { warning( `The selector for ${methodName} of ${displayName} did not specify a value for dependsOnOwnProps.` ) } } } export default function verifySubselectors(mapStateToProps, mapDispatchToProps, mergeProps, displayName) { verify(mapStateToProps, "mapStateToProps", displayName) verify(mapDispatchToProps, "mapDispatchToProps", displayName) verify(mergeProps, "mergeProps", displayName) }selectorFactory.js
這里主要負責獲取處理過的mapStateToProps, mapDispatchToProps, mergeProps和傳入的options,來進行props的合并,最后返回合并后的結(jié)果。其中,當pure為true的時候,會對props進行存儲,便于下一次比較,如果通過比較兩個相同,那么就不改變props對象,減少不必要的re-render。
在connectAdvanced.js里面看到這么一段注釋:
finalPropsSelectorFactoryselectoryFactory方法返回的是一個function,這個function的作用是根據(jù)Redux Store state, props和dispatch計算新的props. 在connectAdvanced中會提供dispatch給selectorFactory,以便selectorFactory可以對actionCreator進行綁定。connectAdvanced獲取的option配置會直接被傳給selectorFactory,其中就包含了displayName和wrappedComponent(其實還有一些對比的方法在里面)。
selectorFactory負責記錄所有的狀態(tài)(props, store state, dispatch, mergedProps),以便在部分狀態(tài)發(fā)生改變,而不影響組件渲染的時候,可以避免不必要的渲染。
export default function 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 ) }
這里只是給mapStateToProps, mapDispatchToProps, mergeProps傳入dispatch和options對象,然后根據(jù)pure的值傳給不同的方法進行處理。
如果pure是true, 那么selectorFactory返回的selector會負責存儲最后結(jié)果。如果結(jié)果沒有發(fā)生改變,那么connectAdvanced的shouldComponentUpdate就會返回false。
如果pure是false, 那么selector永遠會返回一個新的對象,同時shouldComponentUpdate永遠都返回true
這個factory方法會返回一個function,接收Redux Store和ownProps作為參數(shù)。作用是,每次store或ownProps發(fā)生改變以后,調(diào)用這個返回的function,獲取更新后的最終props。
impureFinalPropsSelectorFactoryexport function impureFinalPropsSelectorFactory( mapStateToProps, mapDispatchToProps, mergeProps, dispatch ) { return function impureFinalPropsSelector(state, ownProps) { return mergeProps( mapStateToProps(state, ownProps), mapDispatchToProps(dispatch, ownProps), ownProps ) } }
根據(jù)pure等于false的情況,這里會永遠返回一個新的對象。存粹的、不加任何判斷的調(diào)用mergeProps對幾個props的結(jié)構(gòu)進行合并。
這里返回的值的格式是:(state, ownProps)=>final props。
pureFinalPropsSelectorFactoryexport function pureFinalPropsSelectorFactory( mapStateToProps, mapDispatchToProps, mergeProps, dispatch, { areStatesEqual, areOwnPropsEqual, areStatePropsEqual } ) { let hasRunAtLeastOnce = false // 是否是第一次調(diào)用,第一次調(diào)用不需要做是否改變的檢查 let state // 記憶上一次的state let ownProps // 記憶上一次的ownProps let stateProps // 記憶mapStateToProps返回的props let dispatchProps // 記憶mapDispatchToProps返回的props let mergedProps // 記憶最后合并后的結(jié)果 // 第一次調(diào)用的時候,純粹記住所有的結(jié)果 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 } // 當兩個都發(fā)生改變。。。 function handleNewPropsAndNewState() { stateProps = mapStateToProps(state, ownProps) // ownProps發(fā)生了改變,肯定需要調(diào)用獲取新的props if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps) mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps } // 如果只有父組件傳入的props發(fā)生了改變,那么需要根據(jù)dependsOnOwnProps來進行更新 function handleNewProps() { if (mapStateToProps.dependsOnOwnProps) stateProps = mapStateToProps(state, ownProps) if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps) // 由于ownProps發(fā)生了改變,所以不需要進行檢查,直接調(diào)用mergeProps方法 mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps } // 如果只有Redux store state發(fā)生了改變,那么只用更新mapStateToProps的返回值,因為dispatchProps和Redux State無關(guān) function handleNewState() { const nextStateProps = mapStateToProps(state, ownProps) const statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps) stateProps = nextStateProps if (statePropsChanged) mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps } // 除第一次調(diào)用外,每次都需要對各種結(jié)果進行檢查,然后記錄必要的結(jié)果 function handleSubsequentCalls(nextState, nextOwnProps) { const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps) // 檢查ownProps是否發(fā)生改變 const stateChanged = !areStatesEqual(nextState, state) // 檢查Redux store state是否發(fā)生改變 state = nextState ownProps = nextOwnProps // 根據(jù)改變的不同,調(diào)用不同的方法。減少不必要的運算 if (propsChanged && stateChanged) return handleNewPropsAndNewState() if (propsChanged) return handleNewProps() if (stateChanged) return handleNewState() return mergedProps } return function pureFinalPropsSelector(nextState, nextOwnProps) { return hasRunAtLeastOnce ? handleSubsequentCalls(nextState, nextOwnProps) : handleFirstCall(nextState, nextOwnProps) } }
當pure等于true的時候,需要做出各種檢查來判定是否需要調(diào)用方法,來獲取新的props.
當Redux state發(fā)生改變,ownProps沒變的時候
1) 由于mapDispatchToProps并沒有基于Redux State,所以dispatchProps是需要進行更新的。2) 而mapStateToProps是基于Redux State的,所以需要調(diào)用mapStateToProps方法或許"新的"stateProps。由于State發(fā)生改變,并不一定會造成返回結(jié)果的改變,所以需要根據(jù)檢查后的結(jié)果來判定是否調(diào)用mergeProps方法。
當OwnProps發(fā)生改變,Redux State沒有改變的時候
1) 由于mapDispatchToProps和mapStateToProps都可能基于ownProps,所以需要根據(jù)dependsOnOwnProps屬性來檢查,判斷是否需要調(diào)用方法進行更新。2) ownProps作為mergeProps的一個必要參數(shù),所以不需要做任何判斷,mergePorps必須被調(diào)用
當Redux Store, OwnProps都發(fā)生了改變
綜合之前的兩點,mapStateToProps必須調(diào)用,mapDispatchToProps根據(jù)dependsOnOwnProps屬性調(diào)用,mergeProps必須調(diào)用
在connect定義的時候,一般盡量使用pure:true的情況(默認值),因為在這種情況下,會對props進行差別檢查。如果沒有改變,就不會去調(diào)用connectAdvanced組件去更新。如果內(nèi)部組件同時根據(jù) 除 父組件傳入的props和Redux store的其他狀態(tài)進行更新渲染,那么pure必須是false。
option中的areStatesEqual(默認值為===),areOwnPropsEqual(默認值為shallowEqual), areStatePropsEqual(默認值為shallowEqual), areMergedPropsEqual(默認值為shallowEqual),可以根據(jù)需要來修改這幾個參數(shù),當pure為true的時候,檢查更多不必要的re-render
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88075.html
摘要:返回值決定了在更新的時候,是否要調(diào)用方法進行更新這里通過判斷方法的來進行判斷是否需要,當?shù)臅r候,就是需要。同時,一個影對象會被造出并合并到組件的中。在這種情況下,返回的會被作為真正的。 注:這篇文章只是講解React Redux這一層,并不包含Redux部分。Redux有計劃去學習,等以后學習了Redux源碼以后再做分析;注:代碼基于現(xiàn)在 (2016.12.29) React Redu...
摘要:的作用在文檔中是這么說的給下級組件中的提供可用的的對象。這個文件里的主要是被方法引入,并傳給的,算是一個默認的。表示當前的名稱。這個值表示在里面的值。便于控制,同時某些不需要渲染的,也不會造成渲染。 注:這篇文章只是講解React Redux這一層,并不包含Redux部分。Redux有計劃去學習,等以后學習了Redux源碼以后再做分析注:代碼基于現(xiàn)在(2016.12.29)React ...
摘要:更多相關(guān)介紹請看這特點僅僅只是虛擬最大限度減少與的交互類似于使用操作單向數(shù)據(jù)流很大程度減少了重復代碼的使用組件化可組合一個組件易于和其它組件一起使用,或者嵌套在另一個組件內(nèi)部。在使用后,就變得很容易維護,而且數(shù)據(jù)流非常清晰,容易解決遇到的。 歡迎移步我的博客閱讀:《React 入門實踐》 在寫這篇文章之前,我已經(jīng)接觸 React 有大半年了。在初步學習 React 之后就正式應(yīng)用到項...
摘要:不只為組件提供中的數(shù)據(jù)及擴展方法,它還為定義的組件添加了一系列事件操作,這些事件的核心點就是,然后可以在自己定義的組件內(nèi)獲得。行為功能是對目的功能和有用行為的一種抽象。下一個中間件函數(shù)通常由名為的變量來表示。 redux 這個是好久之前寫的,一直忘記粘過來,里面有一些是寫作格式是我自己定義的,所以和segmentfault的markdown語法有出入,圖片也不能加載,所以原文效果可以在...
閱讀 2804·2023-04-25 18:46
閱讀 697·2021-11-19 09:40
閱讀 2063·2021-09-28 09:36
閱讀 3374·2021-09-10 11:11
閱讀 3453·2019-08-30 15:55
閱讀 1791·2019-08-30 15:54
閱讀 2589·2019-08-29 16:16
閱讀 3536·2019-08-29 15:08