Redux とは?
Redux とは、「Action」と呼ばれるイベントを使用してアプリケーションの状態を管理するライブラリです。React.js を用いる場合は、stateを管理することになります。
Redux のメリットは?
では、なぜ Redux をわざわざ用いるのでしょうか。
Redux は React の単純な state 管理と異なり、**グローバル(複数のコンポーネント間)**での状態(state)管理を行うことができるからです。
また、Redux が提供するパターンやツールを使用することで、アプリケーションの状態(state)が、いつ・どこで、なぜ、そしてどのようにして更新したか、また状態(state)が更新した時のロジックを簡単に理解することができます。
Redux のデータフロー
Redux の state 管理の流れを見ていきましょう!全体的な流れは以下のようになります。
Todo リストを例にとり、1 つ 1 つ掘り下げて見てみましょう。
Action
ユーザの操作により、コンポーネントの state が変わったと想定しましょう。Redux では、state が変わったら Action を発行します。
Actionはtype
プロパティを持つ JavaScript のオブジェクトで、「何をするのか」といった情報をもつ必要があります。
type
プロパティは Action の内容を説明する文字列である必要があり、ドメイン/イベント名
のような命名規則にするのがよいです。
- ドメイン : Action が属するカテゴリ
- イベント : 「何をするのか」を表す文字列
また、Action オブジェクトにはtype
プロパティに関する追加情報を別のプロパティで定義できます。慣例で、payload
というプロパティを利用します。
const addTodoAction = {
type: "todo/todoAdded",
payload: "部屋を掃除する",
};
ActionCreator
ActionCreatorはActionを作成する関数です。通常はこちらを利用するので、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は、stateとActionオブジェクトを受け取り、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 はstateとactionを受け取り、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