Redux Toolkit で Redux の煩わしさから解放される


この記事は[React Advent Calendar 2019](https://qiita.com/advent-calendar/2019/react) の19日目の記事です。（遅れてすいません）  
前日の18日目は [React Context APIを使った非同期通信のハンドリング](https://qiita.com/South_/items/9ef295adbd6c93293723) でした。

今回は [Redux Toolkit](https://redux-toolkit.js.org/) について紹介をします。

## Redux Toolkit とは？
`Redux Toolkit` は、現在 [Redux](https://redux.js.org/) のメインメンテナーの一人である、[Mark Erikson](https://github.com/markerikson) 氏が作成したものです。  
2019年10月に [v1](https://github.com/reduxjs/redux-toolkit/releases/tag/v1.0.0) がリリースされました。

こちらの [Idiomatic Redux: Redux Toolkit 1.0](https://blog.isquaredsoftware.com/2019/10/redux-starter-kit-1.0/) で作成した意図が書かれています。  
そこには、2018年に `@acemarke/redux-starter-kit` (Redux Toolkitの1つ前の名前) としてパッケージが公開される前に `Redux` 上で行われた議論が語られています。  
同記事には [` Redux Starter Kit ` のビジョン](https://github.com/reduxjs/redux-toolkit/issues/82#issuecomment-456261368) も掲載されています。

> - Make it easier to get started with Redux  
> - Simplify common tasks  
> - Opinionated defaults guiding towards "best practices"  
> - Provide solutions to make people stop using the word "boilerplate"  

要はベストプラクティスを使用したテンプレートを用いて、`Redux` を使いやすく、簡素なものにするということです。  

## Redux Toolkit の技術
公式ドキュメントの [What's Included](https://redux-toolkit.js.org/introduction/quick-start/#whats-included) にもだいたい記載されているのですが、Redux Toolkit はこのような技術構成になっています。

- `TypeScript` 製
- `Redux DevTools Extension` でデフォルトで同梱
- middleware は [redux-thunk](https://github.com/reduxjs/redux-thunk)
- [immer](https://github.com/immerjs/immer) を使用した、`immutable` な状態変更
- [Reselect](https://github.com/reduxjs/reselect) を使用した、`memoized` 機能

## Redux Toolkit を使ってみる
公式ドキュメントの [Basic Tutorial: Introducing Redux Toolkit](https://redux-toolkit.js.org/tutorials/basic-tutorial) を使用して、`Redux Toolkit` を使用した場合と、そうでない場合を見比べてみます。

```javascript
// Redux Toolkit を使用していない場合

function counter(state, action) {
  if (typeof state === 'undefined') {
    return 0
  }
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }

var store = Redux.createStore(counter)

document.getElementById('increment').addEventListener('click', function() {
  store.dispatch({ type: 'INCREMENT' })
})
```

```javascript
//  Redux Toolkit を使用した場合

// createSlice を使用
// {
//    name : string,
//    reducer : ReducerFunction,
//    actions : Object<string, ActionCreator>,
// }
// を返す関数
const counterSlice = createSlice({
  name: 'counter', // reducers名
  initialState: 0, // initialState
  reducers: { // reducers
    increment: state => state + 1,
    decrement: state => state - 1
  }
})

// configureStore を使用、middleware や devTools の設定済み
const store = configureStore({
  reducer: counterSlice.reducer
})


document.getElementById('increment').addEventListener('click', () => {
  store.dispatch(counterSlice.actions.increment())
})
```

とても簡素なものになりました。  
この状態で、`Redux DevTools Extension` も使用ができます。  
今回使用したのは [createSlice()](https://redux-toolkit.js.org/api/createSlice) と [configureStore()](https://redux-toolkit.js.org/api/configureStore) になります。   
そのほかにも Action を生成する [createAction()](https://redux-toolkit.js.org/api/createAction) や Reducer を生成する [createReducer()](https://redux-toolkit.js.org/api/createReducer) などが存在します。  
詳しくは、公式ドキュメントの ` API Reference ` に載っているので一読するとよいです。  

## その他
`Redux Toolkit` はドキュメントがかなり整っているので、先ほど紹介した [Basic Tutorial](https://redux-toolkit.js.org/tutorials/basic-tutorial) 以外にも、TODO アプリケーションを例にした [Intermediate Tutorial](https://redux-toolkit.js.org/tutorials/intermediate-tutorial)や Git Hub Issue アプリを作成する [Advanced Tutorial](https://redux-toolkit.js.org/tutorials/advanced-tutorial) のチュートリアルがあります、英語ですがとても分かりやすので、Google翻訳を使用し、コードの写経をするだけでも理解が深まるかと思います。

チュートリアル以外にも [Usage With TypeScript](https://redux-toolkit.js.org/usage/usage-with-typescript) で TyepScript の使用していく例もあるので、TypeScript を使用して Redux アプリケーションを作成する方は一読しておくとよいです。

## 最後に
` Redux Toolkit ` は `Redux` を使用するすべての方にオススメです!  
` Redux ` 公式が推奨するアプローチをまとめた [Redux Style Guide](https://redux.js.org/style-guide/style-guide) でも使用することを勧めています。  
今まで `Redux` を使用する場合は、煩わしいことも多かったのですが、` Redux Toolkit ` を使用すれば、その煩わしさからも解放されると思います。