說明:閱讀本篇文章須要對Redux有必定的瞭解,對Redux不瞭解的同窗可先看看這篇文章Redux技術架構簡介(一)html
爲了讓Redux和React更好的配合,Facebook專門開發了一個npm包--react-redux,能夠這樣引入你的項目: npm install --save react-redux
固然不引用也徹底能夠(Redux包是必需要引用的),只不過會增長一些開發量,還會帶來一些額外的性能開銷。react
Redux的React綁定庫的基本開發思想是展現組件與容器組件相分離。展現組件只負責頁面呈現,不處理數據,不維護狀態;容器組件負責頁面的運行邏輯,獲取展現組件中的消息,處理內部數據,更新狀態等。
npm
React引入redux後,應用中只有單一的state樹,react的每一個組件均可以拋棄state的相關邏輯,改成從props獲取,包括要執行的一些用戶事件行爲。
引入redux後的react組件變爲:redux
class MainContent extends React.Component{ constructor(props){ super(props); this.sortResult = this.sortResult.bind(this); this.showSlider = this.showSlider.bind(this); } sortResult(data){ this.props.setPhoto(data); } showSlider(index){ this.props.showSlider(index); } componentDidMount () { this.props.fetchPosts(); } render(){ let {isFetching, isValidate} = this.props; let sliderNode = null; if(this.props.photo.length){ sliderNode = <PhotoSliderContainer data={this.props.photo} />; } return ( <div className="mainContent"> <Header title="photo" /> <SortContainer data={this.props.photo} sortResult={this.sortResult}/> <PhotoItemsContainer data={this.props.photo} showSlider = {this.showSlider}/> {sliderNode} </div> ); } };
能夠看到,MainContent組件除了展現外,幾乎沒有任何的邏輯處理(subscribe和dispatch的邏輯都放到了容器組件),全部的數據都是經過this.props從父組件中獲取。segmentfault
容器組件實現了將展現組件和redux關聯在一塊兒。技術上講,容器組件就是使用 store.subscribe() 從 Redux state 樹中讀取部分數據,並經過 props 來把這些數據提供給要渲染的組件。建議每一個展現組件對應一個容器組件,這樣能夠很清晰的找到映射關係。架構
從名字上能夠看出,這個函數實現了從state(reducer中定義的)到展現組件props 的映射。示例代碼以下:ide
const mapStateToProps = (state, ownProps) => { return { photo : state.photomainReducer.photoData, video : state.photomainReducer.videoData, isFetching : state.photomainReducer.isFetching, isValidate : state.photomainReducer.isValidate } }
傳入的state是應用中惟一的狀態樹,咱們從相應組件的reducer中讀取state,分別映射到一個自定義屬性中,這樣就能夠在展現組件中直接調用對應屬性(props)了。
mapStateToProps會訂閱 Store,每當state更新的時候,就會自動執行,從新計算 UI 組件的參數,從而觸發 UI 組件的從新渲染。函數
一樣咱們也能夠猜到,這個函數的做用是將指望執行的dispatch方法的返回值映射到展現組件的props上。示例代碼以下:性能
const mapDispatchToProps = (dispatch, ownProps) => { return { slider:(data) => dispatch(photomainAction.showSlider(data)) } }
好比咱們想dispatch一個showSlider的action,經過這個方法映射以後,就能夠直接這樣寫:fetch
this.props.slider(data)
即mapDispatchToProps封裝了dispatch方法。此外,還能夠經過redux提供的bindActionCreators函數進一步封裝,上面的代碼能夠改寫以下:
const mapDispatchToProps = (dispatch, ownProps) => { return bindActionCreators({ slider:photomainAction.showSlider },dispatch); }
若是import時的action名和你想定義的屬性名同樣,甚至還能夠簡化:
const mapDispatchToProps = (dispatch, ownProps) => { return bindActionCreators({slider},dispatch); }
上面2個方法實現了state和action到props的映射,咱們還須要把這2個函數鏈接在一塊兒,而且要關聯到一個具體的展現組件,這樣就能夠在展現組件中使用這種映射關係了。示例代碼以下:
const PhotomainContainer = connect( mapStateToProps, mapDispatchToProps )(Photomain);
其中,Photomain是一個展現組件。
每個容器組件都包含一個對應的展現組件,咱們能夠把這些容器組件當作一個普通的react組件進行組合,整合的最後一步就是如何把store傳入到每一個組件中。
Store保存了整個應用的單一狀態樹,全部容器組件都須要從store中讀取,咱們能夠store做爲屬性傳遞給每一個組件,子組件經過props獲取,可是若是嵌套過深,寫起來會很麻煩。還好,react-redux提供一個叫provider的組件,他可讓全部組件均可以訪問到store(他的實現原理其實是利用了react的context功能),而沒必要顯示的一層層傳遞了。
ReactDOM.render( <Provider store={store}> <PhotomainContainer></PhotomainContainer> </Provider>, $(".main-wrap")[0] );
有一點要注意,provider內的組件只能有一個,因此須要將全部組件先封裝成一個組件再用provider包裹起來。
Redux的引入使React完全脫離了對數據狀態的管理,可讓React更專一於View的展示,實際上這也是react善於作的事情。單獨看react,咱們甚至感受不到redux的存在,使邏輯層和視圖層更加清晰(redux負責邏輯,react負責視圖),固然一部分緣由要歸功於react-redux包作了很好的封裝。
以上就是React與Redux整合的簡單實現。