React + Reduxでカウントアプリを作る

#はじめに
この記事では、React+Reduxを使用してカウントアプリを作ってみたいと思います。
下記が完了している前提で話を進めていくので、インストールされてない方は実施してください。

1. Node.jsのインストール
2. パッケージマネージャー yarnのインストール
3. creat-react-appのインストール

参考：https://qiita.com/rspmharada7645/items/25c496aee87973bcc7a5

#1. プロジェクトを作成する
まず、任意のディレクトリに移動し、create-react-appコマンドでプロジェクトを作成します。

```console
$ create-react-app countApp
```

実行後、下記のようなメッセージが表示されていればOKです。

```
Initialized a git repository.

Success! Created countApp at /Users/******/countApp
```

作成したプロジェクト配下に移動し、下記のstartコマンドを実行します。

```console
$cd countApp
$yarn start
```

実行後、ブラウザが起動し、以下の画面が表示されていればOKです。
<img width="1161" alt="スクリーンショット 2019-04-29 12.28.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263738/ea65f5c2-0904-011c-46c9-83bc3041120f.png">


#2. 必要なパッケージをインストールする

作成したプロジェクト配下に移動します。
今回は`redux`、`react-redux`の２つのパッケージを使用するので、yarnを使ってインストールします。

```console
$cd countApp
$yarn add redux, react-redux
```


#3. Reduxによるカウントアプリを実装する

今回は以下のようなフォルダー構成でカウントアプリを実装していきます。

```
.
 ├──  node_modules
 ├──  public
 ├──  src
      ├── actions
          └── index.js
      ├── components
          └── App.js
      ├── reducers
          ├── index.js
          └── count.js  
      ├── index.js        
      └──  serviceWorker.js 
 ├── index.js
 ├── yarn.lock
 ├── package.json
 └── README.md
```


まず、`actions/index.js`を作成していきます。
ここでは、アクションの定義とアクションクリエーターを作成していきます。

今回は、カウントの値をstateで管理します。stateの状態を変更するアクションは、
カウントを増やす、減らすの２つしかないため、作成するアクションは２つになります。

```actions/index.js
//Action定義
export const INCREMENT = "INCREMENT";
export const DECREMENT = "DECREMENT";

//Action Creater(Action Createrを呼び出すことで、stateの更新が行われる)
export const increment = () =>({
    type : INCREMENT
});

export const decrement = () =>({
    type : DECREMENT
});

```

次に`reducers/count.js`と`reducers/index.js`を作成します。
`count.js`の中で、実行した`action`に応じて、stateの情報を更新します。

```reducers/count.js
import {
    INCREMENT,
    DECREMENT,
} from '../actions';

const initialize = { value : 0 };
export default (count = initialize, action) => {
    switch(action.type){
        case INCREMENT:
            return { value : count.value + 1 };
        case DECREMENT:
            return { value : count.value  - 1 };
        default:
            return count;
    }
}
```
```reducers/index.js
import { combineReducers } from 'redux';
import count from './count';

export default combineReducers({count});
```

次に、`index.js`でstoreの作成とReduxをcomponentに対して利用可能にするために、`Provider`で`Counter`をラップします。

```index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Counter from './components/Counter';
import { Provider } from 'react-redux';
import { createStore } from 'redux';

import reducer from './reducers';
import * as serviceWorker from './serviceWorker';


const store = createStore(reducer);

//Provider（供給する）でラップすることで、stateの情報を共有することが可能
ReactDOM.render(
    <Provider store={store}>
        <Counter />
    </Provider>, 
    document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
```

最後に、コンポーネントの作成をしていきます。

```components/Counter.js
import React, {Component} from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from '../actions';

class Counter extends Component {
  render(){
    return (
      <React.Fragment>
        <div>
          カウント値 : {this.props.value}
        </div>
        <div>
          <button onClick={this.props.increment}>+</button>
          <button onClick={this.props.decrement}>-</button>
        </div>
      </React.Fragment>
    );
  }
}

//reduxで管理しているState情報をPropsで扱えるようにする
const mapStateToProps = state => ({ value : state.count.value});

//Action関数をPropsで扱えるようにする
const mapDispatchToProps = ({increment, decrement});

//componentとRedux Storeを接続する
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
```


#4. カウントアプリを動かしてみよう

yarn startで動かしてみましょう！

```console
$cd countApp
$yarn start
```
下記のような画面が表示されていればOKです。
+ボタンを押した時に、カウントの値が増えて、-ボタンを押した時にカウントの値が減っていればOKです。

![スクリーンショット 2019-05-11 18.30.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263738/91d7d2c4-4a7e-d203-64ae-791cc49c7cd0.png)

次回は、、
[React+Reduxで作るメモアプリ](https://qiita.com/rspmharada7645/private/b2546628abf30f17fc30)