Reduxの処理の流れ

## 概要
最近React+Reduxについて触れる機会があったのでちょっとやってみたら、Reduxの処理がわからなかったので自分の理解用にまとめてみました。

## sample codeの準備と説明 
今回は[sample code](https://github.com/takahiron/sample-redux)を使用して説明していきたいと思います。
githubにcodeと実行手順を記載しているのでここでは割愛します。

まず、このsample codeはどのようなものか
構成は下記になります。

```
$ tree .
├── package.json
├── public
│   └── index.html
└── src
    ├── actions
    │   └── action.js
    ├── components
    │   └── App.js
    ├── containers
    │   └── IOString.js
    ├── index.js
    └── reducers
        └── index.js
```
ここの`public/index.html`と`src/index.js`はreact-scriptsが起動したタイミングで一番最初に呼ばれるファイルになります。

## Reduxの処理の流れ
### 初回読み込み
react-scriptを実行したら最初に`public/index.html`と`src/index.js`が呼ばれます。
`public/index.html`は最終的にjs側で生成したhtmlを貼り付けるだけなので飛ばします。
`src/index.js`では最初の読み込みが行われます。
これは`import`を書いた順に実行されていきます。

```js:src/index.js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import App from './containers/IOString'
import reducer from './reducers'

const store = createStore(reducer)
...
```
その後`createStore`が実行されて`./reducers`配下のindex.jsファイルが呼び出されます。

今回は1つしかないので`./reducers/index.js`が呼ばれます。
自分のイメージでは、ここで呼ばれた処理は今後のアクションによって条件分岐していくものなのであらかじめ呼ばせて準備しておくイメージです。
### reducers
```js:src/reduceres/index.js
export default function reducer(state, action){
  switch(action.type){
    case 'ADD':
      return {no: action.no, text: action.text}
    default:
      return {no: 0, text: "start"}
  }
}
```
今回はaction.typeがADDの時かそれ以外(default)の場合の2択になっています。
ちなみに初期値はdefaultの`{no: 0, text: "start"}`になります。

そのあと、`src/index.js`のProviderにstoreをセットします。

### containers
次に`src/index.js`のAppが呼び出される。
Appの内容は下記になります。

```js:src/containers/IOString.js
import React from 'react'
import { connect } from 'react-redux'
import { ioData } from '../actions/action'
import App from '../components/App'

const mapStateToProps = state => {
  return state
}
 
 const mapDispatchToProps = dispatch => {
  return {
    onClickAdd: text => {dispatch(ioData(text))}
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)
```
`mapStateToProps`は`connect`でReact component と Redux storeをつなげます。
`connect`はReactコンポーネントをReduxストアに接続する役割です。

### components
```js:src/components/App.js
import React from 'react'

let input
export default class App extends React.Component {
  render () {
    return (
      <div>
        <form onSubmit={e => {
          e.preventDefault()
          if(!input.value.trim()) {
            return
          }
          this.props.onClickAdd(input.value)
          input.value = ""
        }}>
         <input ref={node =>{
           input = node
         }} />
         <button>
           add string
         </button>
       </form>
       <span>{this.props.no}:{this.props.text}</span>
      </div>
    )
  }
}
```
ここのHTMLは最終的に`src/index.js`のAPPの箇所に出力されます。
今回は下から説明します。

```
・・・
<span>{this.props.no}:{this.props.text}</span>
・・・
```
ここで宣言されているthis.props群ですが画面で数値と画面で入力した値が入ってきます。
このprops.noとtextは```src/containers/IOString.js```で設定されていた```mapStateToProps```のstateが対象になります。
(おそらくindex.jsで設定されたcreateStoreの引数がmapStateToPropsを通ってきたのかなと思います。)

その上のinputでは、入力した値をinput変数に格納し
formのonSubmitでbuttonが押下されたらinputの内容をonClickAddで飛ばして値を空にしています。

この時onClickAddは```src/containers/IOString.js```のmapDispatchToPropsの値が対象になります。
ここで```src/actions/action.js```に処理を渡し戻り値をdispatchがstoreに通知します。

### action
```js:src/actions/action.js
let noCount = 1
export const ioData = (text) => ({
  type: 'ADD',
  no: noCount++,
  text
})
```

ここではstoreにデータを送信するための情報を作成します。
先ほど```src/components/App.js```で呼ばれたonClickAddは一旦```src/containers/IOString.js```のmapDispatchToPropsに行き、そこに設定してあったactionに移動します。
ここの```ioData = (text)```のtextにはinput変数の値が入ります。
またonCountには```let noCount = 1```で初期値を設定していて、その値のカウントを行なっています。
(リロードしない限りカウントは消えません)
ここで設定された値はstoreを通してcreateStoreで設定されたreduceに向かいます。

そこのreturnに設定していある値を```src/components/App.js```の

```js:src/components/App.js
・・・
<span>{this.props.no}:{this.props.text}</span>
・・・
```
で出力しているという流れでした。

## まとめ
実際に見ただけではわかりづらく、実際に動かして処理の流れを追わないと理解するのは難しいかなと思いました。
今回はざっと書いて見ましたが、部分ごとに深堀したほうがいいところがあると思うので次reduxを書く機会があったら深堀してみようと思います。

sample code
https://github.com/takahiron/sample-redux