Redux の概念と使い方を学ぼう

Posted: 2021/2/23
React/
Redux

Redux とは?

Redux とは、「Action」と呼ばれるイベントを使用してアプリケーションの状態を管理するライブラリです。React.js を用いる場合は、stateを管理することになります。

Redux のメリットは?

では、なぜ Redux をわざわざ用いるのでしょうか。

Redux は React の単純な state 管理と異なり、**グローバル(複数のコンポーネント間)**での状態(state)管理を行うことができるからです。

また、Redux が提供するパターンやツールを使用することで、アプリケーションの状態(state)が、いつ・どこで、なぜ、そしてどのようにして更新したか、また状態(state)が更新した時のロジックを簡単に理解することができます。

Redux のデータフロー

Redux の state 管理の流れを見ていきましょう!全体的な流れは以下のようになります。

redux

Todo リストを例にとり、1 つ 1 つ掘り下げて見てみましょう。

Action

ユーザの操作により、コンポーネントの state が変わったと想定しましょう。Redux では、state が変わったら Action を発行します。

Actiontype プロパティを持つ JavaScript のオブジェクトで、「何をするのか」といった情報をもつ必要があります。

type プロパティは Action の内容を説明する文字列である必要があり、ドメイン/イベント名 のような命名規則にするのがよいです。

  • ドメイン : Action が属するカテゴリ
  • イベント : 「何をするのか」を表す文字列

また、Action オブジェクトにはtype プロパティに関する追加情報を別のプロパティで定義できます。慣例で、payloadというプロパティを利用します。

const addTodoAction = {
  type: "todo/todoAdded",
  payload: "部屋を掃除する",
};

ActionCreator

ActionCreatorActionを作成する関数です。通常はこちらを利用するので、Action オブジェクトを毎回手動で生成する必要はありません。

const addTodo = content => {
  return {
    type: "todo/todoAdded",
    payload: content,
  };
};

Dispatch

ActionCreatorで生成されたActionを呼び出してStoreに渡します。Dispatchは状態を更新する唯一の方法で、store.dispatch() の引数にActionCreatorを入れることで実行できます。

import { configureStore } from "@reduxjs/toolkit";

const store = configureStore({ reducer: todoReducer });

store.dispatch(addTodo("洗濯する"));

Reducer

Reducerは、stateActionオブジェクトを受け取り、state を更新する必要があれば、(state, action) => newState の形式で新しい state を返します。これにより、Store の state が更新されます

また、Reducer は以下のルールに従う必要があります。

  • 前の state と action オブジェクトに基づいて新しい state のみを計算する必要がある
  • 既存の state を変更してはいけない。代わりに state をコピーして新しい state を生成する
  • 非同期処理をしたり、ランダムな値を計算したり、副作用を引き起こしてはいけない

2 について少し説明します。Redux の状態を安全に更新するには state を直接書き換えるような処理を行ってはいけません。

const state = {
  id: 1,
  message: "Hello",
};
// 直接書き換えるのはよくない
state.message = "Good morning";

そのため、スプレッド構文など用いて state のコピーを作成して新しい state を生成します。

newState = { ...state };

これらを踏まえて、Reducer の例は以下のようになります。

const initialState = { content: "hoge" };

function todoReducer(state = initialState, action) {
  // actionによってstateを更新するロジックを変更する
  if (action.type === "todo/todoAdded") {
    // stateのコピーを生成し、値を更新して返す
    return {
      ...state,
      // 新しい値をコピーして更新
      value: action.payload,
    };
  }
  // stateを更新する必要がなければそのまま返す
  return state;
}

Reducer はstateactionを受け取り、action のtypeによって state のコピーを作ることで更新していることがわかります。

Store

Reducer から返された新たな state を Store というオブジェクトでまとめて管理します。Store は Redux Toolkit のconfigureStore にオブジェクト形式で reducer を渡すことで作成できます。

また、getState() メソッドを用いることで更新された state を取得することができます。

import { configureStore } from "@reduxjs/toolkit";
// reducerを渡す
const store = configureStore({ reducer: counterReducer });
// 更新されたstateを取得する
console.log(store.getState());

まとめ

Redux を用いることで、React アプリケーションの複数コンポーネント間での state 管理が容易になることがわかりました。

また、Redux のデータフローは以下のようになります。

  • ユーザの操作により、コンポーネントの state が変更
  • ActionCreator によって Action を生成
  • Action を dispatch
  • Reducer が Action と state を受け取り、store の state を更新
  • Store から更新された state を取得

次回は実際に Redux を組み込んだ簡単なアプリケーションを開発していきます!

それでは 🙌

https://redux.js.org/tutorials/essentials/part-1-overview-concepts