Takahiro Octopress Blog

-1から始める情弱プログラミング

redux-actionsについて学ぼう!〜iOSエンジニアが苦しんだReduxの基礎(4)〜

はじめに

前回connect()を使ったReact&ReduxでのWebサイトの実装について見ていきました。
今回は処理簡略化するためによく使われるredux-actionsを利用した書き方について見ていきましょう。
これもまた基本が理解できていないとハマりポイントとなるため、知っておきたい内容の1つになります。

Counterサンプルで学ぼう!

公式ReduxページのExampleの先頭に書かれている Counter を見ていきましょう。
今回もわかりやすさのために同じサンプルを利用します。(redux-actionsを利用した実装に改変しています。)
実装するWebサイトは下図の通りです。

Counter Example画面

実装されている機能としては下記の4つになります。

  • 「+」ボタンを選択するとClick数が+1される
  • 「-」ボタンを選択するとClick数が-1される
  • 「Increment if odd」ボタンを選択するとClick数が奇数のときのみ+1される
  • 「Increment async」ボタンを選択すると1秒後にClick数が+1される

フォルダ構成

まずは例によってフォルダ構成を見ていきます。

1
2
3
4
5
6
7
8
9
10
11
12
counter
├── public
     └── index.html
└── src
     ├── index.js
     ├── actions
          └── index.js
     ├── reducers
          └── index.js
     ├── components
          └── Counter.js
     └── node_modules

redux-actionsを利用したActionsの実装

これまでActionsおよびCreate Actionsはシンプルに下記のように実装していました。

1
2
3
4
5
6
7
8
9
10
// actions/index.js
const INCREMENT = { type: 'INCREMENT' }
const DECREMENT = { type: 'DECREMENT' }

export function increment() {
  return INCREMENT;
}
export function decrement() {
  return DECREMENT;
}

これをredux-actionsを利用すると下記のように実装できます。

1
2
3
4
5
6
7
8
// actions/index.js
import { createAction } from 'redux-actions'

export const INCREMENT = ('INCREMENT')
export const DECREMENT = ('DECREMENT')

export const increment = createAction(INCREMENT)
export const decrement = createAction(DECREMENT)

ポイントはcreateActionメソッドを利用している点です。
このメソッドは「第一引数を指定すること」 = 「typeプロパティを設定したオブジェクトを返却すること」になります。
つまり、

1
2
3
4
5
6
7
8
export const increment = createAction(INCREMENT)

/*
createActionでやっていることを素で書くと下記の通り
export const increment = () => {
  return { type: 'INCREMENT' }
}
*/

ということです。

redux-actionsを利用したReducersの実装

これまでReducersの実装は下記のようにしていました。

1
2
3
4
5
6
7
8
9
10
11
// reducers/index.js
export default (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

これをredux-actionsを利用すると下記のように実装できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
// reducers/index.js
import { handleActions } from 'redux-actions'

const initialState = 0

export default handleActions({
  INCREMENT: (state, action) => {
    return state + 1
  },
  DECREMENT: (state, action) => {
    return state - 1
  }
}, initialState)

ポイントはhandleActionsメソッドを利用している点です。
handleActionsは第一引数に各Reducerをマッピングするのに利用し、第二引数でstateの初期値を設定します。
第二引数で設定する初期値を予めconst initialState = 0とすることで、(state = 0, action)の代わりの役目を果たしています。

まとめ

今回はおまけ回として書いてみました。
やっと基本的なことが少しずつわかってきた段階なので、これからもっと学ばなければいけないことが多いと感じています。
Reduxは他の言語でも特徴をまねたライブラリがわんさか出てきているので、ここで学んだことがWebに閉じた話ではなく、いろいろなところで活かせると信じています。
これからも機を見て、Reduxについて書いていければと思います。
ということで本日はここまで。

Comments