1.UI组件Example,只接受this.props数据,包括reducer出来的数据state,
以及dispatch方法.
2.容器组件
const store = createStore(reducer);
经过mapStateToProps将reducer返回的state做为this.props传入.
经过mapDispatchToProps将action做为this.props传入.
经过connect方法将这两个方法与Example组件链接起来,返回一个容器组件.react
import React, { Component } from 'react'; import { render } from 'react-dom'; import { createStore } from 'redux'; import { Provider, connect } from 'react-redux'; import reducer from '../reducers/reducer6.js'; import { addAction, delAction } from '../actions/action2.js'; import Example from '../components/Example5.js'; const store = createStore(reducer); function mapStateToProps(state) { return { count: state.count }; } function mapDispatchToprops(dispatch) { return { add: () => dispatch(addAction()), del: () => dispatch(delAction()) }; } const App = connect(mapStateToProps, mapDispatchToprops)(Example) render( <Provider store={ store }> <App /> </Provider>, document.getElementById('root') );
import React, { Component } from 'react'; class Example extends Component { render() { const { count, add, del } = this.props; return ( <div> <p>count: { count }</p> <p><button onClick={ add }>add</button></p> <p><button onClick={ del }>del</button></p> </div> ); } } export default Example;
1.React-Redux将全部组件分红两大类:UI组件和容器组件.
2.UI组件有如下几个特征:redux
import React, { Component } from 'react'; class Counter extends Component { render() { const { value, onIncreaseClick } = this.props; return ( <div> <span>{ value }</span> <button onClick={ onIncreaseClick }>Increase</button> </div> ); } } export default Counter;
1.只负责UI的呈现,不带有任何业务逻辑 2.没有状态(即不使用this.state这个变量) 3.全部数据都由参数(this.props)提供 4.不适用任何redux的API
由于不含有状态,UI组件又被称为'纯组件',即它跟纯函数同样,纯粹由参数决定它的值.dom
// Action const increaseAction = { type: 'increase' }; // Reducer function counter(state = { count: 0 }, action) { const count = state.count; switch (action.type) { case 'increase': return { count: count + 1 } default: return state; } } // Store const store = createStore(counter); // Map Redux state to component props function mapStateToProps(state) { return { value: state.count }; } // Map Redux actions to component props function mapDispatchToProps(dispatch) { return { onIncreaseClick: () => dispatch(increaseAction) }; } // Connected Component const App = connect(mapStateToProps, mapDispatchToProps)(Counter);
容器组件的特征偏偏相反ide
1.负责管理数据和业务逻辑,不负责UI的呈现 2.带有内部状态 3.使用redux的API
UI组件负责UI的呈现,容器组件负责管理数据和逻辑.
react-redux规定,全部的UI组件都由用户提供,容器组件则是由react-redux自动生成,也就是说,
用户负责视觉层,状态管理则是所有交给它.函数
react-redux提供connect方法,用于从UI组件生成容器组件.
connect的意思,就是将这两种组件连起来.
const App = connect(mapStateToProps, mapDispatchToProps)(Counter);
Counter是UI组件,App就是由React-Redux经过connect方法自动生成的容器组件.
可是,由于没有定义业务逻辑,上面这个容器组件毫无心义,只是Ui组件的一个单纯的包装层.
为了定义业务逻辑,须要给出下面两方面的信息.this
1.输入逻辑:外部的数据(即state对象)如何转化为UI组件的参数. 2.输出逻辑:用户发出的动做如何变为Action对象,从UI组件传出去
connect方法接受两个参数:mapStateToProps和mapDispatchToProps,他们定义了UI组件的业务逻辑,
前者负责输入逻辑,即将state映射到Ui组件的参数(props),后者负责输出逻辑,即将用户对UI组件的操做映射成Action.spa
mapStateToProps是一个函数,它的做用就是像它的名字那样,创建一个从(外部的)state对象到(Ui组件的)props对象的映射关系.
做为函数,mapStateToProps执行后应该返回一个对象,里面的每个键值对就是一个映射.
mapStateToProps会订阅store,每当state更新的时候,就会自动执行,从新计算UI组件的参数,从而
触发UI组件的从新渲染.
mapStateToProps的第一个参数是state对象.code
mapDispatchToProps是connect函数的第二个参数,用来创建UI组件的参数到store.dispatch方法的映射,
也就是说,他定义了哪些用户的操做应该看成Action,传给Store,它能够是一个函数,也能够是一个对象.
若是mapDispatchToProps是一个函数,会获得dispatch和ownProps(容器组件的props对象)两个参数.
做为函数,应该返回一个对象,该对象的每一个键值对都是一个映射,定义了UI组件的参数怎样发出Action.component
connect方法生成容器组件之后,须要让容器组件拿到state对象,才能生成UI组件的参数.
react-redux提供Provider组件,可让容器组件拿到state.
Provider在根组件外面包了一层,这样一来,App的全部子组件就默认均可以拿到state了.
它的原理是React组件的context属性.
react-redux自动生成的容器组件的代码,就相似上面这样,从而拿到store.对象
render( <Provider store={ store }> <App /> </Provider>, document.getElementById('root') );
使用React-Router的项目,与其余项目也没有不一样之处,也是使用Provider在Router外面包一层,毕竟Provider的惟一功能就是传入store对象.
const root = ({ store }) => ( <Provider store={ store }> <Router> <Route path="/" component={ App }> </Router> </Provider> );