Redux(状態管理フレームワーク)とは

## はじめに
こちらはフロントエンドで使用される状態管理フレームワーク`Redux`に関する記事になります。

**ただ2023年5月時点で、`Redux`を使用することは非推奨となっていることにご注意ください。**
以下`Redux`の公式ページにも`Redux toolkit`の使用が推奨されています。

https://redux.js.org/introduction/getting-started

今回はReactを想定したコードになっております。

## Reduxとは
Reduxは、`シングルページアプリケーション (Single Page Application, SPA) において、グローバルな状態 (state) を更新および管理するためのフレームワーク`のことです。

Reduxは、アプリケーションの状態を一つのストア (store) で管理し、その状態を変更するためのアクション (action) を定義します。アクションはアプリケーション内のさまざまなコンポーネントで発生するイベントやユーザーの操作を表現し、それに対応するリデューサー (reducer) によって状態が変更されます。

![スクリーンショット (1201).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/1e1ab352-bfd0-f6d1-7747-ef957cdcea3a.png)

上記で出てきた用語について解説します。

## Action
Actionとは
> アプリケーション内で何かしらのイベントや操作が発生した際に作成されるオブジェクト。Actionは、アプリケーションの状態を変更するための情報を持っています。

```javascript: 
{
  type: 'ACTION_TYPE',
  payload: /* データや情報などの追加のプロパティ */
}
```

typeプロパティは、アクションの種類を示す文字列であり、一般的に定数として定義されます。アクションタイプは、アプリケーション内で発生する異なるイベントや操作を区別するために使用されます。

payloadプロパティは、アクションに関連するデータや情報を持つ任意のプロパティです。状態の変更に必要なデータがある場合、payloadプロパティにそれらの値を含めることができます。

## ActionCreator
ActionCreattorとは

> アクションを作成して返す関数のこと。アクションクリエータは、アプリケーション内でアクションを生成するために使用されます。引数として必要な情報やデータ（payload）を受け取り、それを含んだアクションオブジェクトを生成してストア内のリデューサーに渡されます。

```javascript: actionCreator.js
export function actionCreatorName(payload) {
  return {
    type: 'ACTION_TYPE',
    payload: payload
  }
}
```

## dispatch
dispatchとは
> アクションをストア内のリデューサーに送るためのメソッドのこと。アプリケーション内でアクションを発行するために使用されます。
```javascript: ViewComponent.jsx
// react-reduxからdispatchを作成するためのuseDispatchという関数をインポートする必要があります。
import { useDispatch } from 'react-redux'; 
import { actionCreatorName } from './actionCreator.js';

const ViewComponent = () => {
    const dispatch = useDispatch();

    const onClickHandler = () => {
        dispatch(actionCreatorName(payload));
    }

    /* 省略 */
}
```

上記はreact-reduxというライブラリからdispatch関数を使うための、useDispatch関数をインポートしています。

ユーザーのUIイベントに登録されたonClickHandlerが呼び出されると、dispatch関数の引数に渡されたactionCreatorName関数によってオブジェクトが生成され、ストア内のリデューサーに送られます。

## Reducer
Reducerとは
> アクションを受け取り、新しい状態を生成する純粋関数です。リデューサーはReduxストアの中心的な部分であり、アプリケーションの状態の変更を処理します。

```javascript: reducer.js
export function reducer(state = initialState, { type, payload }) {
  switch (type) {
    case 'ACTION_TYPE':
      // payloadを使って、状態の変更を処理する。
      return newState;
    default:
      return state;
  }
}
```

リデューサーは、現在の状態 (state) とディスパッチされたオブジェクト(type, payload)を引数として受け取ります。アクションのタイプに応じて、適切な状態の変更ロジックを実行し、新しい状態を返します。

リデューサーは、アプリケーションの状態の変更を一元管理するために非常に重要です。アクションがディスパッチされると、リデューサーが呼び出され、渡ってきたアクションオブジェクトに基づいて状態の変更を行います。そして、変更された状態が新しい状態としてストアに保存されます。

## Store
Storeとは
> アプリケーションの状態を保持し、状態の変更を管理する中心的なオブジェクトです。ストアはReduxの重要な概念の一つであり、状態の変更とデータフローの管理を担当します。

```javascript: store.js
import { createStore, combineReducers } from "redux";
import { reducer } from "./reducer.js"

const reducers = combineReducers({
  counter: reducer,
});

export default createStore(reducers);
```

ReduxからcreateStoreとcombineReducersをインポートしています。createStoreはストアを作成するための関数であり、combineReducersは複数のリデューサーを結合するための関数です。

combineReducers関数を使用して、counterというキーでreducerを結合します。combineReducers関数は、指定したキーとリデューサーのペアをオブジェクトとして受け取り、それらを組み合わせたルートリデューサーを生成します。

createStore関数を使用して、ルートリデューサーreducersを基にストアを作成します。そして、作成したストアをデフォルトエクスポートしています。

## Storeのデータを参照するには
```javascript: index.jsx
import Counter from "./components/Counter";
import { Provider } from "react-redux";
import store from "./store"

const Index = () => {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
};

export default Index;
```

react-reduxからProviderコンポーネントをインポートしています。ProviderコンポーネントはReduxのストアをReactアプリケーションに提供する役割を持ちます。

また、Providerコンポーネントを使用してReactアプリケーション全体にReduxのストアを提供し、Counterコンポーネントがストアの状態を参照・更新できるようにしています。

```javascript: Counter.jsx
import { useSelector } from "react-redux"

const Counter = () => {
  const state = useSelector(state => state);
  return <h3>{state.counter}</h3>
};

export default Counter;
```
useSelectorフックを使用してReduxのストアの状態を参照し、stateという変数に代入しています。コールバック関数 state => state は、ストアの状態全体を返すため、stateにはストアの状態オブジェクトが格納されます。

useSelectorはストアの状態の変更を検知し、コンポーネントを再レンダリングするため、状態の変化に合わせて画面の表示も自動的に更新されます。

## おわりに
冒頭でも言いましたが`Redux`は現状非推奨なフレームワークで、Reduxの公式ページにも`Redux toolkit`の使用が推奨されていることにご注意ください。

間違いなどありましたらご指摘いただけると幸いです:bow:

最後まで記事をご覧いただきありがとうございました。

## 参考

https://www.youtube.com/watch?v=FBMA34gUsgw&t=81s

https://qiita.com/kitagawamac/items/49a1f03445b19cf407b7

https://qiita.com/mpyw/items/a816c6380219b1d5a3bf

https://www.udemy.com/course/react-complete-guide/