react-reduxの導入

* react-redux の特徴
    * ReactとReduxの構成要素（StoreやAction）を疎結合にするためのライブラリです。
* 主な機能
    * Provider
        * connectを使用することで、コンポーネントのpropsにstoreの内容を渡しておくことができます。

* react-redux のインストール

~~~react-redux
npm install -save react-redux
~~~

* 簡単なサンプル  

~~~index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from './reducers/reducer';
import CountContainer from './containers/container';

const store = createStore(reducer);

ReactDOM.render(
    <Provider store={ store }>
        <CountContainer />
    </Provider>,
    document.getElementById('root')
);
~~~
ここでは、Provider経由でコンテナ（CountContainer）にStoreを渡しています。

~~~containers/container.js
import React from 'react';
import { connect } from 'react-redux';
import { createCountUpAction, createCountDownAction } from '../actions/countActionCreators';
import CountComponent from '../components/component';

function mapStateToProps({ currentCount }) {
    return { currentCount };
}
function mapDispatchToProps(dispatch) {
    return {
        countUp(currentCount) {
            dispatch(createCountUpAction(currentCount));
        },
        countDown(currentCount) {
            dispatch(createCountDownAction(currentCount));
        }
    };
}
export default connect(mapStateToProps, mapDispatchToProps)(CountComponent)
~~~
ここでは、Storeの内容（stateとdispach）をコンポーネント（CountComponent）のpropsに設定しています。
stateの設定処理は、mapStateToProps()に記載し、
dispatchの設定処理は、mapDispatchToPropsに記載します。
ここでreturnされたオブジェクトが、コンポーネント（CountComponent）のpropsに設定されます。
それによって、コンポーネント（CountComponent）からStoreの内容（stateとdispach）を利用することが出来るようになります。

~~~reducers/reducer.js
import { COUNT_UP, COUNT_DOWN } from '../actions/countActionCreators';

const initialState = { currentCount : 1 };
 
// 初期表示時、
// stateには、initialStateが設定されます。
// また、action.typeには、"@@redux/INITl.3.o.v.o.o"といったランダムな文字列が渡されます。
export default function reducer (state = initialState, action) {
    switch (action.type) {
        case COUNT_UP :
            return Object.assign({}, { currentCount : state.currentCount + 1 });
        case COUNT_DOWN :
            return Object.assign({}, { currentCount : state.currentCount - 1 });
        default :
            return state;
    }
}
~~~
Reducerです。
ここに、stateの更新処理を書きます。
このreducerはcreateStore()の引数に渡していた関数です。
reducerが実行されるのは、dispatch()が実行された時です。
reducerが実行されると、stateはreducer()からreturnされたオブジェクトの内容に更新されます。

~~~actions/countActionCreators.js
export const COUNT_UP = 'UP';
export const createCountUpAction = (currentCount)  => ({
        type : COUNT_UP,
        payload : { currentCount }
});

export const COUNT_DOWN = 'DOWN';
export const createCountDownAction = (currentCount)  => ({
    type : COUNT_DOWN,
    payload : { currentCount }
});
~~~
ActionCreatorです。
ここには、dispatch()に渡すActionオブジェクトを作成する処理を書きます。

~~~components/component.js
import React from 'react';

export default class CountComponent extends React.Component {
    render() {
        const { currentCount, countUp, countDown } = this.props;
        return (
            <React.Fragment>
                <pre>
                    <div>Count=[ { currentCount } ]</div><br/>

                    <button onClick={
                        () => {
                            countUp(currentCount)
                        }
                    }>Up</button>

                    <br/><br/>

                    <button onClick={
                        () => {
                            countDown(currentCount)
                        }
                    }>Down</button>
                </pre>
            </React.Fragment>
        );
    }
}
~~~
コンポーネントの定義です。
ここでは、コンテナで紐づけたcurrentCountやcountUp、countDownをprops経由で利用できます。
なお、コンポーネントとコンテナの紐付けは、Providerによって行っています。

以上で、
コンポーネントから、store、dispatch、actionを意識しなくて済むようになり、
reactとreduxを疎結合にすることが出来るようになります。
  
* ソースコード  
[GitHub](https://github.com/kazuyuki-murayama/react-redux-01-initial)
* ルーティングについて  
[react-router の適用](https://qiita.com/k-murayama/items/41bcfdb1756cebbe8e06)