React Redux入門　


初投稿ながらも、頑張って書いてみました。

小規模な開発をする上で、生のReactに不満はなかったのですが、今後のスキルアップのために「Redux」について触れていきたいと思います。

##Redux について
Reactだけでも、フロントエンドの開発はできます。
Reactと独自実装でも状態管理はできますが、いい感じに状態管理周りをまとめてくれるフレームワークの一つが Redux です。

##Reduxの導入
###react用モジュール
・react
・react-dom
###redux連携用モジュール
・redux
・react-redux

```package.json
{
  "name": "react-redux-tutorial-counter",
  "version": "1.0.0",
  "description": "Sample app",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "browserify src/index.js -o dist/bundle.js -t [ babelify --presets [ react es2015 ] ]"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "browserify": "12.0.1",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babelify": "^7.2.0"
  },
  "dependencies": {
    "react": "^15.0.1",
    "react-dom": "^15.0.1",
    "react-redux": "^4.4.2",
    "redux": "^3.4.0"
  }
}
```

##Reduxを構成するコンポーネントの種類
今回出てくるコンポーネントは下記の二つです。

①Provider
Providerコンポーネントはreact-reduxが提供する実在するReactコンポーネントです。
唯一、Storeを持つことを許された存在で、Stateやdispatch関数を配下のContainerコンポーネントで利用可能にします。

②Container
Containerは connect関数でReactコンポーネントをラッピングしたものです。

##フォルダ構成
###・dist
コンパイルしたものをここのディレクトリに出力します。

```dist/index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Redux</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>
```
###・src
srcはactions, components, containers, reducers, storeから構成されます。

```javascript:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import configureStore from './store/configureStore';
import App from './containers/app';

const store = configureStore();

ReactDOM.render(
  //ストアを作ってproviderに渡す。
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
```
index.htmlの中のroot要素に、Reactで生成したDOMを流し込む。

**store**

```javascript:src/store/configureStore.js
import { createStore } from 'redux';
import reducer from '../reducers/index';

export default function configureStore() {
    const store = createStore(reducer);
    return store;
}
```
Storeを作成する際に、ReducerをcreateStore()メソッドの第一引数として渡すことで、Store内でstateの更新が可能になります。
また、ReduxにはMiddlewareという概念があり、必要に応じてMiddlewareを追加することで、非同期処理が可能になったり、Stateのログを見れるようになります。

**actions**

```javascript:src/actions/app.js
export default {
  increment: () => {
    return { type: 'INCREMENT' }
  },
  decrement: () => {
    return { type: 'DECREMENT' }
  }
}
```
actionはStateを変えるためやAPIを叩くときに、Viewから呼ばれます。
actionTypeを付与することで、reducerでどのようにStateが変更されるのかを区別します

**reducers**

```javascript:src/reducers/index.js
// 初期ステート設定
const initialState = {
  fuga: 0
}

// actionに応じてステート変更
export default function reducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT': {
      return { fuga: state.fuga + 1 }
    }
    case 'DECREMENT': {
      return { fuga: state.fuga - 1 }
    }
    default:
      return state
  }
}
```
state の状態を更新するためのロジックを書く部分。

**containers**

```javascript:src/containers/app.js
import React from 'react'
import { connect } from 'react-redux'
import App from '../components/app'
import AppActions from '../actions/app'

function mapStateToProps(state) {
  return state
}

// clickでactionを飛ばず
function mapDispatchToProps(dispatch) {
  return {
    Increment_Click: () => { dispatch(AppActions.increment()) },
    Decrement_Click: () => { dispatch(AppActions.decrement())}
  }
}

export default connect(//これが子コンポーネントで使える要素（props）
  mapStateToProps,
  mapDispatchToProps
)(App)
```
mapStateToProps関数とmapDispatchToProps関数は、それぞれStoreのstateとdispatchメソッドをpropsを通して、Containerで扱えるようにするものです。

**components**

```javascript:src/components/app.js
import React from 'react';
//reduxやactionsをimportしていない。→ 必要なモノは親から全てprops経由で受け取っている
export default class App extends React.Component {
  render() {
    return (
        <div>
          <span>{this.props.fuga}</span><br/>
          <button onClick={ () => this.props.Increment_Click() }>＊増加＊</button>
          <button onClick={ () => this.props.Decrement_Click() }>＊減少＊</button>
        </div>
    );
  }
}
```

##ビルドする
```
npm run build
```
dist下にbundle.jsが生成されるので、最初に作ったindex.htmlにアクセスします。

##参考にさせていただきました
[React + Redux入門初歩　実際に一からアプリを構築してみる](https://qiita.com/pentamania/items/859fe5f2f7e9cf12d6ca)