React Redux: 从文档看源码 - Connect工具类篇(2)
注:这篇文章只是讲解React Redux这一层,并不包含Redux部分。Redux有计划去学习,等以后学习了Redux源码以后再做分析 Connect工具类篇(1) Connect工具类篇(2)verifySubselectors.js这里有四个参数:
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,mergeProps,displayName) { verify(mapStateToProps,'mapStateToProps',displayName) verify(mapDispatchToProps,'mapDispatchToProps',displayName) verify(mergeProps,'mergeProps',displayName) } selectorFactory.js这里主要负责获取处理过的mapStateToProps,mergeProps和传入的options,来进行props的合并,最后返回合并后的结果。其中,当pure为true的时候,会对props进行存储,便于下一次比较,如果通过比较两个相同,那么就不改变props对象,减少不必要的re-render。 在connectAdvanced.js里面看到这么一段注释:
finalPropsSelectorFactoryexport 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,options.displayName) } const selectorFactory = options.pure ? pureFinalPropsSelectorFactory : impureFinalPropsSelectorFactory return selectorFactory( mapStateToProps,options ) } 这里只是给mapStateToProps,mergeProps传入dispatch和options对象,然后根据pure的值传给不同的方法进行处理。
这个factory方法会返回一个function,接收Redux Store和ownProps作为参数。作用是,每次store或ownProps发生改变以后,调用这个返回的function,获取更新后的最终props。 impureFinalPropsSelectorFactoryexport function impureFinalPropsSelectorFactory( mapStateToProps,dispatch ) { return function impureFinalPropsSelector(state,ownProps) { return mergeProps( mapStateToProps(state,ownProps),mapDispatchToProps(dispatch,ownProps ) } } 根据pure等于false的情况,这里会永远返回一个新的对象。存粹的、不加任何判断的调用mergeProps对几个props的结构进行合并。 这里返回的值的格式是: pureFinalPropsSelectorFactoryexport function pureFinalPropsSelectorFactory( mapStateToProps,{ areStatesEqual,areOwnPropsEqual,areStatePropsEqual } ) { let hasRunAtLeastOnce = false // 是否是第一次调用,第一次调用不需要做是否改变的检查 let state // 记忆上一次的state let ownProps // 记忆上一次的ownProps let stateProps // 记忆mapStateToProps返回的props let dispatchProps // 记忆mapDispatchToProps返回的props let mergedProps // 记忆最后合并后的结果 // 第一次调用的时候,纯粹记住所有的结果 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 } // 当两个都发生改变。。。 function handleNewPropsAndNewState() { stateProps = mapStateToProps(state,ownProps) // ownProps发生了改变,肯定需要调用获取新的props if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch,ownProps) mergedProps = mergeProps(stateProps,ownProps) return mergedProps } // 如果只有父组件传入的props发生了改变,那么需要根据dependsOnOwnProps来进行更新 function handleNewProps() { if (mapStateToProps.dependsOnOwnProps) stateProps = mapStateToProps(state,ownProps) if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch,ownProps) // 由于ownProps发生了改变,所以不需要进行检查,直接调用mergeProps方法 mergedProps = mergeProps(stateProps,ownProps) return mergedProps } // 如果只有Redux store state发生了改变,那么只用更新mapStateToProps的返回值,因为dispatchProps和Redux State无关 function handleNewState() { const nextStateProps = mapStateToProps(state,ownProps) const statePropsChanged = !areStatePropsEqual(nextStateProps,stateProps) stateProps = nextStateProps if (statePropsChanged) mergedProps = mergeProps(stateProps,ownProps) return mergedProps } // 除第一次调用外,每次都需要对各种结果进行检查,然后记录必要的结果 function handleSubsequentCalls(nextState,nextOwnProps) { const propsChanged = !areOwnPropsEqual(nextOwnProps,ownProps) // 检查ownProps是否发生改变 const stateChanged = !areStatesEqual(nextState,state) // 检查Redux store state是否发生改变 state = nextState ownProps = nextOwnProps // 根据改变的不同,调用不同的方法。减少不必要的运算 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的时候,需要做出各种检查来判定是否需要调用方法,来获取新的props.
一点总结:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |