[React] Redux Toolkitを活用して楽しよう...

### 概要

先日、`Redux`に関する記事を投稿しました。
本記事では、`Redux`をより使いやすくするための`Redux Toolkit`について解説していこうと思います。

https://qiita.com/PenPe/items/c38f08dddb85540cddf4

---

### Redux Toolkit とは？

`Redux Toolkit`は、`Redux`の公式ツールキットであり、`Redux`の使用を簡単にし、開発プロセスを合理化するための一連のツールと機能を提供します。

特に、コードのボイラープレートを削減し、直感的なAPIを提供することで、開発者の生産性を向上させることを目的としています。

---

#### なぜRedux Toolkitを利用するのか
- **ボイラープレートの削減**: ユーティリティを提供することで、ボイラープレートコードを大幅に削減できる

- **強力なデバッグツール**: `Redux DevTools`とシームレスに統合されており、タイムトラベル・デバッギングやアクションのトレースが容易

- **ベストプラクティスの推奨**: `Redux Toolkit`は、`Redux`のベストプラクティスを推奨しているため、コードの一貫性を保つのに役立つ

---

### 主要API

まずは Redux Toolkitをインストールします。
```shell
npm install @reduxjs/toolkit
```

Redux Toolkitは、４つの主要なAPIを提供しています。

#### :memo: createAction

`createAction`は、新しいアクションを簡単に作成するためのユーティリティです。
`Action Creator`の作成を簡素化します。

```typescript
import { createAction } from '@reduxjs/toolkit';

// { type: 'counter/increment' }
const increment = createAction('counter/increment');

// { type: 'counter/decrement' }
const decrement = createAction('counter/decrement');
```

##### 型指定
`createAction`で型を指定することで、ペイロードの型を明示的に定義できます。

```typescript
import { createAction } from '@reduxjs/toolkit';

// ペイロードの型指定
interface Payload {
  amount: number;
}

// { type: 'counter/increment', payload: { amount: number } }
const increment = createAction<Payload>('counter/increment');

// { type: 'counter/decrement', payload: { amount: number } }
const decrement = createAction<Payload>('counter/decrement');
```

---

#### :memo: createReducer

`createReducer`は、リデューサーを簡単に定義するための関数です。

従来の`switch`文を使ったリデューサーの代わりに、`builder`オブジェクトを使用して各アクションタイプに対応する処理を記述します。

```typescript
import { createReducer } from '@reduxjs/toolkit';

import { increment, decrement } from './actions.ts';

interface CounterState {
  count: number;
}

const initialState: CounterState = { count: 0 };

const counterReducer = createReducer(initialState, (builder) => {
  builder
    .addCase(decrement, (state) => {
      if (state.count > 0) {
        state.count--;
      }
    })
    .addCase(increment, (state) => {
      state.count++;
    });
});

export default counterReducer;
```

---

#### :memo: createSlice

`createSlice`は、アクション、アクションクリエーター、リデューサーをまとめて定義するための方法です。

```typescript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface CounterState {
  count: number;
}

const initialState: CounterState = { count: 1 };

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
    added:(state, action: PayloadAction<number>) => {
      state.count += action.payload;
    }
  },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
```

##### 引数
- **第一引数:** スライスの名前を指定。アクションタイプの`prefix`として使用される
- **第二引数:** スライスの初期状態
- **第三引数:** アクションタイプごとのリデューサー関数をオブジェクトとして指定

##### sliceの特徴
- **アクションとリデューサーを1つのファイルに記載:** アクションクリエーターとリデューサーが同じファイルに記載されるため、関連するロジックが1か所にまとまり、管理が容易になる
- **re-ducksパターンに準拠:** アクションタイプ、アクションクリエーター、リデューサーが1つのスライスファイルにまとめられ、re-ducksパターンに準拠した構成となる

---

#### :memo: createReducer vs createSlice
`createReducer` と `createSlice`の使い分けについて考えます。

**`createReducer`の使用:**
よりシンプルな`reducer`が必要で、特定のアクションにのみ対応する場合や、特定の部分的な機能のためだけに`reducer`を定義したい場合に適しています。また、アクションクリエーターが不要である、またはカスタムのアクションクリエーターを別途定義したい場合にも有効です。

**`createSlice`の使用:**
ほとんどの場合は`createSlice`を使用することが推奨されます。
アクションタイプ、アクションクリエーター、`reducer`を一元的に管理できるため、コードの一貫性を保ちやすく、またボイラープレートの削減にもつながります。

---

#### :memo: configureStore

`configureStore`は、ストアの設定を簡単に行うための関数です。
ミドルウェアの設定やデフォルトのDevToolsサポートなどが自動的に含まれています。

```tsx
// Providers.tsx
import { FC, PropsWithChildren } from 'react';

import { configureStore } from '@reduxjs/toolkit';
import { Provider as ReduxProvider } from 'react-redux';

import counterSlice from './counterSlice';

const store = configureStore({ reducer: counterSlice.reducer });
const Providers: FC<PropsWithChildren> = ({ children }) => (
  <ReduxProvider store={store}>
    {children}
  </ReduxProvider>
);

export default Providers;
```

---

### Redux DevTools

`Redux DevTools`は、アプリケーションの状態をデバッグするための強力なツールです。
`Redux Toolkit`と組み合わせて使用することで、デバッグプロセスがさらに効率的になります。

#### :memo: タイムトラベル・デバッギング

`Redux DevTools`を使用すると、過去のアクションに戻り、その状態を再現することができます。これにより、バグの原因を特定しやすくなります。

- **アクション履歴の確認:** すべてのディスパッチされたアクションの履歴を記録
- **状態の再現:** 過去のアクションに戻り、その時点の状態を再現
- **アクションの取り消しと再実行:** 任意のアクションを取消、再実行することで、アクションがアプリケーションに与える影響を詳細に分析できる

---

### まとめ
以上です！
ボイラープレートがここまで削減できるのであれば、積極的に活用していきたいと思いました :sparkles: