摘要:負(fù)責(zé)記錄所有的狀態(tài),以便在部分狀態(tài)發(fā)生改變,而不影響組件渲染的時(shí)候,可以避免不必要的渲染。作用是,每次或發(fā)生改變以后,調(diào)用這個(gè)返回的,獲取更新后的最終。由于發(fā)生改變,并不一定會(huì)造成返回結(jié)果的改變,所以需要根據(jù)檢查后的結(jié)果來判定是否調(diào)用方法。
注:這篇文章只是講解React Redux這一層,并不包含Redux部分。Redux有計(jì)劃去學(xué)習(xí),等以后學(xué)習(xí)了Redux源碼以后再做分析
注:代碼基于現(xiàn)在(2016.12.29)React Redux的最新版本(5.0.1)
Connect工具類篇(1)
Connect工具類篇(2) verifySubselectors.js這里有四個(gè)參數(shù):
mapStateToProps, mapDispatchToProps, mergeProps都是經(jīng)過mapDispatchToProps, mapStateToProps, mergeProps封裝過的
displayName是option里面?zhèn)魅氲?br>主要做的是檢查傳入的mapStateToProps,mapDispatchToProps,mergeProps是否存在,由于這里的對(duì)象是經(jīng)過幾個(gè)map方法封裝過的,所以不存在就說明開發(fā)傳入的值是錯(cuò)誤的。同時(shí)檢查是否有dependsOnOwnProps這個(gè)屬性,如果沒有給一個(gè)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, 因?yàn)閙ergeProps方法不需要 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
這里主要負(fù)責(zé)獲取處理過的mapStateToProps, mapDispatchToProps, mergeProps和傳入的options,來進(jìn)行props的合并,最后返回合并后的結(jié)果。其中,當(dāng)pure為true的時(shí)候,會(huì)對(duì)props進(jìn)行存儲(chǔ),便于下一次比較,如果通過比較兩個(gè)相同,那么就不改變props對(duì)象,減少不必要的re-render。
在connectAdvanced.js里面看到這么一段注釋:
finalPropsSelectorFactoryselectoryFactory方法返回的是一個(gè)function,這個(gè)function的作用是根據(jù)Redux Store state, props和dispatch計(jì)算新的props. 在connectAdvanced中會(huì)提供dispatch給selectorFactory,以便selectorFactory可以對(duì)actionCreator進(jìn)行綁定。connectAdvanced獲取的option配置會(huì)直接被傳給selectorFactory,其中就包含了displayName和wrappedComponent(其實(shí)還有一些對(duì)比的方法在里面)。
selectorFactory負(fù)責(zé)記錄所有的狀態(tài)(props, store state, dispatch, mergedProps),以便在部分狀態(tài)發(fā)生改變,而不影響組件渲染的時(shí)候,可以避免不必要的渲染。
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對(duì)象,然后根據(jù)pure的值傳給不同的方法進(jìn)行處理。
如果pure是true, 那么selectorFactory返回的selector會(huì)負(fù)責(zé)存儲(chǔ)最后結(jié)果。如果結(jié)果沒有發(fā)生改變,那么connectAdvanced的shouldComponentUpdate就會(huì)返回false。
如果pure是false, 那么selector永遠(yuǎn)會(huì)返回一個(gè)新的對(duì)象,同時(shí)shouldComponentUpdate永遠(yuǎn)都返回true
這個(gè)factory方法會(huì)返回一個(gè)function,接收Redux Store和ownProps作為參數(shù)。作用是,每次store或ownProps發(fā)生改變以后,調(diào)用這個(gè)返回的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的情況,這里會(huì)永遠(yuǎn)返回一個(gè)新的對(duì)象。存粹的、不加任何判斷的調(diào)用mergeProps對(duì)幾個(gè)props的結(jié)構(gòu)進(jìn)行合并。
這里返回的值的格式是:(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)用的時(shí)候,純粹記住所有的結(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 } // 當(dāng)兩個(gè)都發(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來進(jìn)行更新 function handleNewProps() { if (mapStateToProps.dependsOnOwnProps) stateProps = mapStateToProps(state, ownProps) if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps) // 由于ownProps發(fā)生了改變,所以不需要進(jìn)行檢查,直接調(diào)用mergeProps方法 mergedProps = mergeProps(stateProps, dispatchProps, ownProps) return mergedProps } // 如果只有Redux store state發(fā)生了改變,那么只用更新mapStateToProps的返回值,因?yàn)閐ispatchProps和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)用外,每次都需要對(duì)各種結(jié)果進(jìn)行檢查,然后記錄必要的結(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)用不同的方法。減少不必要的運(yùn)算 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) } }
當(dāng)pure等于true的時(shí)候,需要做出各種檢查來判定是否需要調(diào)用方法,來獲取新的props.
當(dāng)Redux state發(fā)生改變,ownProps沒變的時(shí)候
1) 由于mapDispatchToProps并沒有基于Redux State,所以dispatchProps是需要進(jìn)行更新的。2) 而mapStateToProps是基于Redux State的,所以需要調(diào)用mapStateToProps方法或許"新的"stateProps。由于State發(fā)生改變,并不一定會(huì)造成返回結(jié)果的改變,所以需要根據(jù)檢查后的結(jié)果來判定是否調(diào)用mergeProps方法。
當(dāng)OwnProps發(fā)生改變,Redux State沒有改變的時(shí)候
1) 由于mapDispatchToProps和mapStateToProps都可能基于ownProps,所以需要根據(jù)dependsOnOwnProps屬性來檢查,判斷是否需要調(diào)用方法進(jìn)行更新。2) ownProps作為mergeProps的一個(gè)必要參數(shù),所以不需要做任何判斷,mergePorps必須被調(diào)用
當(dāng)Redux Store, OwnProps都發(fā)生了改變
綜合之前的兩點(diǎn),mapStateToProps必須調(diào)用,mapDispatchToProps根據(jù)dependsOnOwnProps屬性調(diào)用,mergeProps必須調(diào)用
在connect定義的時(shí)候,一般盡量使用pure:true的情況(默認(rèn)值),因?yàn)樵谶@種情況下,會(huì)對(duì)props進(jìn)行差別檢查。如果沒有改變,就不會(huì)去調(diào)用connectAdvanced組件去更新。如果內(nèi)部組件同時(shí)根據(jù) 除 父組件傳入的props和Redux store的其他狀態(tài)進(jìn)行更新渲染,那么pure必須是false。
option中的areStatesEqual(默認(rèn)值為===),areOwnPropsEqual(默認(rèn)值為shallowEqual), areStatePropsEqual(默認(rèn)值為shallowEqual), areMergedPropsEqual(默認(rèn)值為shallowEqual),可以根據(jù)需要來修改這幾個(gè)參數(shù),當(dāng)pure為true的時(shí)候,檢查更多不必要的re-render
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/88075.html
摘要:返回值決定了在更新的時(shí)候,是否要調(diào)用方法進(jìn)行更新這里通過判斷方法的來進(jìn)行判斷是否需要,當(dāng)?shù)臅r(shí)候,就是需要。同時(shí),一個(gè)影對(duì)象會(huì)被造出并合并到組件的中。在這種情況下,返回的會(huì)被作為真正的。 注:這篇文章只是講解React Redux這一層,并不包含Redux部分。Redux有計(jì)劃去學(xué)習(xí),等以后學(xué)習(xí)了Redux源碼以后再做分析;注:代碼基于現(xiàn)在 (2016.12.29) React Redu...
摘要:的作用在文檔中是這么說的給下級(jí)組件中的提供可用的的對(duì)象。這個(gè)文件里的主要是被方法引入,并傳給的,算是一個(gè)默認(rèn)的。表示當(dāng)前的名稱。這個(gè)值表示在里面的值。便于控制,同時(shí)某些不需要渲染的,也不會(huì)造成渲染。 注:這篇文章只是講解React Redux這一層,并不包含Redux部分。Redux有計(jì)劃去學(xué)習(xí),等以后學(xué)習(xí)了Redux源碼以后再做分析注:代碼基于現(xiàn)在(2016.12.29)React ...
摘要:精讀原文介紹了學(xué)習(xí)源碼的兩個(gè)技巧,并利用實(shí)例說明了源碼學(xué)習(xí)過程中可以學(xué)到許多周邊知識(shí),都讓我們受益匪淺。討論地址是精讀源碼學(xué)習(xí)如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。 1. 引言 javascript-knowledge-reading-source-code 這篇文章介紹了閱讀源碼的重要性,精讀系列也已有八期源碼系列文章,分別是: 精讀《Immer.js》源...
摘要:更多相關(guān)介紹請(qǐng)看這特點(diǎn)僅僅只是虛擬最大限度減少與的交互類似于使用操作單向數(shù)據(jù)流很大程度減少了重復(fù)代碼的使用組件化可組合一個(gè)組件易于和其它組件一起使用,或者嵌套在另一個(gè)組件內(nèi)部。在使用后,就變得很容易維護(hù),而且數(shù)據(jù)流非常清晰,容易解決遇到的。 歡迎移步我的博客閱讀:《React 入門實(shí)踐》 在寫這篇文章之前,我已經(jīng)接觸 React 有大半年了。在初步學(xué)習(xí) React 之后就正式應(yīng)用到項(xiàng)...
摘要:不只為組件提供中的數(shù)據(jù)及擴(kuò)展方法,它還為定義的組件添加了一系列事件操作,這些事件的核心點(diǎn)就是,然后可以在自己定義的組件內(nèi)獲得。行為功能是對(duì)目的功能和有用行為的一種抽象。下一個(gè)中間件函數(shù)通常由名為的變量來表示。 redux 這個(gè)是好久之前寫的,一直忘記粘過來,里面有一些是寫作格式是我自己定義的,所以和segmentfault的markdown語法有出入,圖片也不能加載,所以原文效果可以在...
閱讀 2819·2023-04-25 18:46
閱讀 707·2021-11-19 09:40
閱讀 2074·2021-09-28 09:36
閱讀 3382·2021-09-10 11:11
閱讀 3461·2019-08-30 15:55
閱讀 1802·2019-08-30 15:54
閱讀 2596·2019-08-29 16:16
閱讀 3542·2019-08-29 15:08