connect
方法生成容器组件以后,需要让容器组件拿到state
对象,才能生成 UI 组件的参数。
一种解决方法是将state
对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state
传下去就很麻烦。
React-Redux 提供Provider
组件,可以让容器组件拿到state
。
import { Provider } from 'react-redux'import { createStore } from 'redux'import todoApp from './reducers'import App from './components/App'let store = createStore(todoApp);render(<Provider store={store}><App /></Provider>,document.getElementById('root'))
上面代码中,Provider
在根组件外面包了一层,这样一来,App
的所有子组件就默认都可以拿到state
了。
它的原理是React
组件的context
属性,请看源码。
class Provider extends Component {getChildContext() {return {store: this.props.store};}render() {return this.props.children;}}Provider.childContextTypes = {store: React.PropTypes.object}
上面代码中,store
放在了上下文对象context
上面。然后,子组件就可以从context
拿到store
,代码大致如下。
class VisibleTodoList extends Component {componentDidMount() {const { store } = this.context;this.unsubscribe = store.subscribe(() =>this.forceUpdate());}render() {const props = this.props;const { store } = this.context;const state = store.getState();// ...}}VisibleTodoList.contextTypes = {store: React.PropTypes.object}
React-Redux
自动生成的容器组件的代码,就类似上面这样,从而拿到store
。