console だけでわかる Redux 後編　~actionCreator/middleware 編~

そんな訳で、[前回](https://qiita.com/KONDO-Yuuki/items/357abff3fe327cf473b9)に続きコンソールでreduxを触っていこうと思います。

## action creator

さて、まずは前回同様、単純な数をカウントアップするcounterReducerを作っていきましょう。
ただし、今回は前回と違い、actionに数を指定して、指定した数だけカウントアップするする様にします。

```js

const redux = require('redux');
const counterReducer = (state = { counter: 0 }, action) => {
  if (action.type === 'COUNT_UP') {
    return { counter: state.counter + action.count };
  } else {
    return state;
  }
};

const storeA = redux.createStore(counterReducer);
```

これにactionをdispatchすると、以下の様に動作します。

```js
const countActionTwo = { type: 'COUNT_UP', count: 2 };
storeA.dispatch(countActionTwo);
storeA.getState();
// ->　{ counter: 2 }

const countActionThree = { type: 'COUNT_UP', count: 3 };
storeA.dispatch(countActionThree);
storeA.getState();
// ->　{ counter: 5 }
```

countActionほげを毎回定義するの、面倒くさいですね？
actionを返す関数を定義しましょう。

```js
// ↑のコードの続き
const createCountAction = (count) => { return { type: 'COUNT_UP', count }};
storeA.dispatch(createCountAction(１０));
storeA.getState();
// ->　{ counter: １５ }
storeA.dispatch(createCountAction(２０));
storeA.getState();
// ->　{ counter: ３５ }
```
これがactionCreatorです。


## middleware
middlewareは、actionの前後に処理を挟み込むための関数です。
storeを生成する際、`redux.applyMiddleware`を使ってstoreに登録します。

```js
// ↑のコードの続き

// COUNT_UPアクションが渡ってきた場合、前後の数値を表示するmiddleware
const middleware = store => next => action => {
  if(action.type === 'COUNT_UP'){
  console.log('before')
  console.log(action.count)
  console.log(store.getState())
  next(action);
  console.log('after')
  console.log(store.getState())
  return
  }
  next(action)
}

const storeB = redux.createStore(
  counterReducer,
  redux.applyMiddleware(middleware)
  )
storeA.dispatch(createCountAction(１０));
// -> before
// -> 10
// -> { counter: 0 }
// -> after
// -> { counter: 10 }

```


上記の例ではconsole.logを呼んでいるだけですが、storeを操作して別のactionをdispatchしたり、actionを書き換えたりする事もできます。

```js
// countが0だったら{ type:'COUNT_UP' count:1 } をdispatchするmiddleware
const zeroIsOneMiddleware = store => next => action => {
  if(action.type === 'COUNT_UP' && action.count === 0){
    store.dispatch({ type:'COUNT_UP' count:1 })
  }
  next(action);
}

// 10以上のCOUNT_UPを無効にする
const denialOverTenMiddleware = store => next => action => {
  if(action.type === 'COUNT_UP' && action.count > 10){
    const overwriteAction = { type:'COUNT_UP' count:10 }
  }
  next(overwriteAction);
}

```
middlewareは複数登録することができ、登録した順にnext()で次のmiddlewareが呼ばれます。
無駄に見た目が複雑になる為掲載は控えますが、興味がある人は複数middlewareを定義して、action実行時どこにあるコードがどのタイミングで呼ばれるかを確認してみて下さい。

## 最後に
以上がreduxの主要な機能です。[^1]
非同期処理用やviewとの連動、actionのスタイルの統一などなどの課題を解決するため公開されている[様](https://github.com/reduxjs/react-redux)[々](https://github.com/reduxjs/redux-thunk)[な](https://github.com/redux-saga)[ラ](https://github.com/pburtchaell/redux-promise-middleware)[イ]()[ブ](https://github.com/erikras/redux-form)[ラ](https://github.com/zalmoxisus/redux-devtools-extension)[リ](https://github.com/redux-utilities/redux-actions)を組合わせて使っていくことになります。
とはいえ、redux自体はこのように非常に薄いライブラリです。
コアとなる部分が十全に理解できているのと居ないのでは、周辺ライブラリの理解速度が全然違うので、このようなまとめを書いてみました。
この記事が、皆さんの開発の一助になれば幸いです。

**それでは、良いフロントエンドライフを！**


[^1]: store.subscribe()は、入門レベルでは使わないと思ったので割愛しました。