庖丁解牛React-Redux(二): connect

connect API

  上篇文章庖丁解牛React-Redux(一): connectAdvanced介绍了react-redux的ProviderconnectAdvanced几个重要API的原理,其中connectAdvancedconnect函数的基础,这篇文章将主要介绍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:
    若是这个参数被传递,返回新的组件将会订阅Redux的store的更新(update)。这意味着任什么时候刻store更新,mapStateToProps将会被调用。mapStateToProps必须返回一个纯对象(plain object),这个对象将会合并进组件的属性(props)。若是你不想订阅store的更新,能够给mapStateToProps参数传递null或者undefinedgithub

    若是你的mapStateToProps函数被声明接受两个参数,mapStateToProps在调用时第一个参数是store state,传递给链接组件(connected component)的属性将会被做为第二个参数。若是链接组件接受到新的props(浅比较),mapStateToProps也会再次调用。redux

注意: 在一些更高级的状况下,你须要更好的控制渲染的性能,mapStateToProps能够返回一个函数。这种场景下,返回的函数将会被做为特定组件实例的mapStateProps()函数。这容许你能够对每一个实例缓存。但大部分应用用不到。api

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,用来避免从新渲染并调用mapStateToPropsmapDispatchToPropsmergeProps时基于各自的等值比较函数来比较所涉及到的stateprops对象。
    • [areStatesEqual] (Function): 若是参数puretrue,用来比较传入的store与以前的store值。默认值: strictEqual (===)。
    • [areOwnPropsEqual] (Function):若是参数puretrue,用来比较传入的props与以前的props值。默认值: strictEqual (===)。
    • [areStatePropsEqual] (Function):若是参数puretrue,用以比较mapStateToProps函数的结果与以前的结果值。
    • [areMergedPropsEqual] (Function): 若是参数puretrue,比较mergeProps函数的结果与以前的值。默认值为:shallowEqual。
    • [storeKey] (String): 用以从context获取store的key值。你仅仅可能在有多个store值的状况下才须要这个选项,默认值为:store

connect源码

  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函数,经过柯里化的方式首先接受如下参数: connectHOCmapStateToPropsFactoriesmapDispatchToPropsFactoriesmergePropsFactoriesselectorFactory。  

connectHOC

  传入用来生成链接到store的高阶组件(HOC),默认是以前介绍过的connectAdvanced。   

selectorFactory

  selectorFactory用来生成selector,第一个参数将传入connectAdvanced。咱们知道传入connectAdvancedselectorFactory函数主要是初始化selector函数。selector函数在每次connector component须要计算新的props都会被调用,selector函数会返回纯对象(plain object),这个对象会做为props传递给被包裹的组件(WrappedComponent)。selectorFactory的函数签名为:

selectorFactory(dispatch, factoryOptions): selector(state, ownProps): props (Function)复制代码

  咱们来看看reduxselectorFactory是怎么定义的:  

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,经过一系列的初始化函数分别生成了mapStateToPropsmapDispatchToPropsmergeProps(初始化函数随后会详细介绍)。而后会在非生产环境下对上述三个函数进行验证(验证主要涉及到该函数是否为空和函数中是否有dependsOnOwnProps属性,这个属性随后会介绍的)。随后即是函数的重点部分,根据options.pure是否为true,选择恰当的selectorFactory,而后返回selectorFactory(...args)
  当options.purefalse时,selectorFactory的值为:impureFinalPropsSelectorFactory:

function impureFinalPropsSelectorFactory( mapStateToProps, mapDispatchToProps, mergeProps, dispatch ) {
  return function impureFinalPropsSelector(state, ownProps) {
    return mergeProps(
      mapStateToProps(state, ownProps),
      mapDispatchToProps(dispatch, ownProps),
      ownProps
    )
  }
}复制代码

  咱们知道,selectorFactory会返回selector函数,返回的函数会接受两个参数:stateownProps并最终返回属性传递给被包裹的组件。咱们发现impureFinalPropsSelectorFactory很是的简单,只是单纯的将要求的参数传递给mapStateToPropsmapDispatchToProps,并将其结果连同ownProps一块儿传递给mergeProps,并将最后mergeProps的结果做为selector函数的结果。这个结果最终会传递给被包裹组件,这个函数没有什么难度并且很是符合connect函数的API。
  但咱们知道在默认状况下,options.puretrue。所以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相比,只是作了缓存,保存了stateownProps以及mapStateToPropsdispatchPropsmergedProps的结果值。

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。其中areOwnPropsEqualareStatesEqual分别用来判断props和state如今的值与缓存的值是否相等函数。handleSubsequentCalls首先判断state、props的先后值是否有变化,而后缓存了stateownProps。若是props和state都发送改变了,返回handleNewPropsAndNewState的结果,若是props改变了,返回handleNewProps的运行结果。若是state改变,返回handleNewState运行结果,不然若是stateprops都没发生改变,说明都没有发生改变。直接返回以前缓存的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的值去判别是否运行mapDispatchToPropsdependsOnOwnProps的值主要是用来判别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
}复制代码

  理解了handleNewPropsAndNewStatehandleNewProps将会很是简单,分别去判别statedispatchProps是否与ownProps相关。以判别是否须要从新运行mapStateToPropsmapDispatchToProps。最终将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值挂钩的。若是puretrue的话,selectorFactory返回的selector会对stateprops等值都会缓存,而后会根据具体的场景,尽量使得传入被包裹组件的值改动最少(即尽量返回相同的值),其目的就是减小没必要要的渲染。当purefalse值,不会作任何的缓存。   

mapStateToProps起源

  看完了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中第一个实参是你传入connectmapStateToProps。第二个实参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返回给被包裹组件。由于返回的老是一个常量,因此dependsOnOwnPropsfalse,表示返回给被包裹组件的值与链接到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是能够返回一个函数的,若是返回的值为一个函数,这个函数将会被做为proxymapStateToProps,再次去执行proxy。   

mapDispatchToProps起源

  
  再去了解一下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
}复制代码

  若是你已经看懂了wrapMapToPropsConstantwrapMapToPropsFunc的函数的话,mapDispatchToPropsFactories也就不难了。若是传入的mapStateToProps的值是一个对象的话,会调用whenMapDispatchToPropsIsObject。继而调用了wrapMapToPropsConstant并传入的参数是函数:dispatch => bindActionCreators(mapDispatchToProps, dispatch)。根据咱们以前经验,那么传递给被包裹的组件的属性将是:bindActionCreators(mapDispatchToProps, dispatch)的运行结果,即被dispatch包裹的action

  若是没有传入mapDispatchToProps函数的话,调用whenMapDispatchToPropsIsMissing。传入函数wrapMapToPropsConstant的参数为:dispatch => ({ dispatch }),那么被包裹的组件接受的参数便是storedispatch方法。
  
  若是传入的mapDispatchToProps是一个函数,调用whenMapDispatchToPropsIsFunction函数。从而调用wrapMapToPropsFunc(mapDispatchToProps, 'mapDispatchToProps')。运行的原理与运行wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps')基本相同,能够参照以前。   

mergeProps起源

//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,再之后的运行过程当中,若是你传入的参数puretrue而且先后的mergedProps值不一样时(比较函数你能够自定义)才会传入新的属性,不然将传入以前的缓存值,以此来优化没必要要的渲染。

  到此为止,咱们基本已经在代码层面讲完了connect函数的原理,文章很长,有的地方可能相对比较难理解,建议你们均可以去从总体上看看react-redux的源码。react-redux源码解读系列接下来会以其余的角度去分析react-redux,欢迎你们继续关注。

相关文章
相关标签/搜索