React-Redux的用法

基本流程

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;

UI組件

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自動生成,也就是說,
用戶負責視覺層,狀態管理則是所有交給它.函數

connect()

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

mapStateToProps是一個函數,它的做用就是像它的名字那樣,創建一個從(外部的)state對象到(Ui組件的)props對象的映射關係.
做爲函數,mapStateToProps執行後應該返回一個對象,裏面的每個鍵值對就是一個映射.
mapStateToProps會訂閱store,每當state更新的時候,就會自動執行,從新計算UI組件的參數,從而
觸發UI組件的從新渲染.
mapStateToProps的第一個參數是state對象.code

mapDispatchToProps

mapDispatchToProps是connect函數的第二個參數,用來創建UI組件的參數到store.dispatch方法的映射,
也就是說,他定義了哪些用戶的操做應該看成Action,傳給Store,它能夠是一個函數,也能夠是一個對象.
若是mapDispatchToProps是一個函數,會獲得dispatch和ownProps(容器組件的props對象)兩個參數.
做爲函數,應該返回一個對象,該對象的每一個鍵值對都是一個映射,定義了UI組件的參數怎樣發出Action.component

<Provider>組件

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路由庫

使用React-Router的項目,與其餘項目也沒有不一樣之處,也是使用Provider在Router外面包一層,畢竟Provider的惟一功能就是傳入store對象.

const root = ({ store }) => (
    <Provider store={ store }>
        <Router>
            <Route path="/" component={ App }>
        </Router>
    </Provider>
);
相關文章
相關標籤/搜索