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> );