LoginSignup
7
8

More than 5 years have passed since last update.

Reduxの処理の流れ

Last updated at Posted at 2017-12-06

概要

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

sample codeの準備と説明

今回はsample codeを使用して説明していきたいと思います。
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.htmlsrc/index.jsはreact-scriptsが起動したタイミングで一番最初に呼ばれるファイルになります。

Reduxの処理の流れ

初回読み込み

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

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

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の内容は下記になります。

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)

mapStateToPropsconnectでReact component と Redux storeをつなげます。
connectはReactコンポーネントをReduxストアに接続する役割です。

components

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

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

src/components/App.js
・・・
<span>{this.props.no}:{this.props.text}</span>
・・・

で出力しているという流れでした。

まとめ

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

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

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8