說明:閱讀本篇文章須要對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從父組件中獲取。bash
容器組件實現了將展現組件和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上。示例代碼以下:post
const mapDispatchToProps = (dispatch, ownProps) => {
return {
slider:(data) => dispatch(photomainAction.showSlider(data))
}
}
複製代碼
好比咱們想dispatch一個showSlider的action,經過這個方法映射以後,就能夠直接這樣寫:性能
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整合的簡單實現。