react-redux中的Provider解析

react-redux中有两大核心方法

  • connect
  • Provider

本文要说的是Provider,connect请看这里

Provider的作用

  • Provider是作为整个App的容器,在你原有的App Container的基础上再包上一层
  • 接受Redux的store作为props,并将其声明为context的属性之一
  • 子组件可以在声明了contextTypes之后可以方便的通过this.context.store访问到store

Provider源码分析

// Provider 依赖react,导入react中元素
import { Component, PropTypes, Children } from 'react'
// 导入store验证规则以及警告提示方法
import storeShape from '../utils/storeShape'
import warning from '../utils/warning'

// 标识是否已经收到警告
let didWarnAboutReceivingStore = false
// 此方法主要用来警告当前的对象是否和传入的对象相同
function warnAboutReceivingStore() {
  if (didWarnAboutReceivingStore) {
    return
  }
  didWarnAboutReceivingStore = true

  warning(
    ' does not support changing `store` on the fly. ' +
    'It is most likely that you see this error because you updated to ' +
    'Redux 2.x and React Redux 2.x which no longer hot reload reducers ' +
    'automatically. See https://github.com/reactjs/react-redux/releases/' +
    'tag/v2.0.0 for the migration instructions.'
  )
}

// Provider是一个内部组建
export default class Provider extends Component {

  // 构造方法传入props和context
  constructor(props, context) {
    super(props, context)
    this.store = props.store
  }

  // 返回从构造方法传递的store,将store传递给子孙component
  getChildContext() {
    return { store: this.store }
  }

  // 返回仅有的一个子元素,否则(没有子元素或超过一个子元素)
  // 报错且不渲染任何东西。 这也说明Provider下必须只能是一个
  // 子元素
  render() {
    return Children.only(this.props.children)
  }
}

// 如果我们运行的环境是production,则还需要定义
// componentWillReceiveProps原型方法
if (process.env.NODE_ENV !== 'production') {
  Provider.prototype.componentWillReceiveProps = function (nextProps) {
    const { store } = this
    const { store: nextStore } = nextProps
    // 如果当前对象与传递的对象不一样,则发出警告
    if (store !== nextStore) {
      warnAboutReceivingStore()
    }
  }
}

Provider.propTypes = {
  store: storeShape.isRequired,
  children: PropTypes.element.isRequired
}
Provider.childContextTypes = {
  store: storeShape.isRequired
}

Provider使用示例

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import App from './containers/count'
import configureStore from './store/configureStore'

const store = configureStore();

render(
    
        
    ,
    document.getElementById('app')
);

完整代码请看这里


参考资料:
https://github.com/ckinmind/ReactCollect/issues/57
https://my.oschina.net/997155658/blog/709155

你可能感兴趣的:(react-redux中的Provider解析)