React與Redux整合技術簡介

說明:閱讀本篇文章須要對Redux有必定的瞭解,對Redux不瞭解的同窗可先看看這篇文章Redux技術架構簡介(一)html

1. React中引入react-redux

爲了讓Redux和React更好的配合,Facebook專門開發了一個npm包--react-redux,能夠這樣引入你的項目:
npm install --save react-redux
固然不引用也徹底能夠(Redux包是必需要引用的),只不過會增長一些開發量,還會帶來一些額外的性能開銷。react

2. 展現組件與容器組件

Redux的React綁定庫的基本開發思想是展現組件與容器組件相分離。展現組件只負責頁面呈現,不處理數據,不維護狀態;容器組件負責頁面的運行邏輯,獲取展現組件中的消息,處理內部數據,更新狀態等。 npm

3. 展現組件的實現

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

4. 容器組件的實現

容器組件實現了將展現組件和redux關聯在一塊兒。技術上講,容器組件就是使用 store.subscribe() 從 Redux state 樹中讀取部分數據,並經過 props 來把這些數據提供給要渲染的組件。建議每一個展現組件對應一個容器組件,這樣能夠很清晰的找到映射關係。架構

mapStateToProps函數

從名字上能夠看出,這個函數實現了從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 組件的從新渲染。函數

mapDispatchToProps函數

一樣咱們也能夠猜到,這個函數的做用是將指望執行的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);
}
複製代碼

connect函數

上面2個方法實現了state和action到props的映射,咱們還須要把這2個函數鏈接在一塊兒,而且要關聯到一個具體的展現組件,這樣就能夠在展現組件中使用這種映射關係了。示例代碼以下:

const PhotomainContainer = connect(
    mapStateToProps,
    mapDispatchToProps
)(Photomain);
複製代碼

其中,Photomain是一個展現組件。 每個容器組件都包含一個對應的展現組件,咱們能夠把這些容器組件當作一個普通的react組件進行組合,整合的最後一步就是如何把store傳入到每一個組件中。

5. 傳入Store

Store保存了整個應用的單一狀態樹,全部容器組件都須要從store中讀取,咱們能夠store做爲屬性傳遞給每一個組件,子組件經過props獲取,可是若是嵌套過深,寫起來會很麻煩。還好,react-redux提供一個叫provider的組件,他可讓全部組件均可以訪問到store(他的實現原理其實是利用了react的context功能),而沒必要顯示的一層層傳遞了。

ReactDOM.render(
    <Provider store={store}>
        <PhotomainContainer></PhotomainContainer>
    </Provider>,
    $(".main-wrap")[0]
);
複製代碼

有一點要注意,provider內的組件只能有一個,因此須要將全部組件先封裝成一個組件再用provider包裹起來。

6. 總結

Redux的引入使React完全脫離了對數據狀態的管理,可讓React更專一於View的展示,實際上這也是react善於作的事情。單獨看react,咱們甚至感受不到redux的存在,使邏輯層和視圖層更加清晰(redux負責邏輯,react負責視圖),固然一部分緣由要歸功於react-redux包作了很好的封裝。

以上就是React與Redux整合的簡單實現。

參考

Redux 中文文檔
Redux 入門教程-阮一峯

相關文章
相關標籤/搜索