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(
'<Provider> 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(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app')
);
完整代码请看这里
参考资料:
https://github.com/ckinmind/ReactCollect/issues/57
https://my.oschina.net/997155658/blog/709155