🦔

【基本】Reduxの仕組みを図でイメージしてみる

2022/10/23に公開約5,400字

まずはこの画像(引用元:Redux Application Data Flow)を理解するところから始める。
お金の状態を例にしているみたいです。

State(状態)

  • お金が0円の状態から始まる。

UI

  • ボタンなどがあり、お金を増やしたり、減らしたりしている。

Dispatch

  • Dispatch→通知するみたいな意味。
  • Event Handlerとは、イベントを処理していると考える。
  • 10円増えましたよ!などをAction(オブジェクト)としてStoreに通知する。

Store

  • Storeの中には、StateとReducerが入っている。
  • Reducerは「なにかを変更する」みたいな意味。
  • State(以前の状態0円)とAction(オブジェクト)が同時にReducerにきていることが分かる。

最終的にReducerによってStateの0円が10円に変更されます。
ひとつづつ分解して考えていくことでReduxの仕組みのイメージができてきました。

カウントアップの仕組みを作成してログで確認してみる

まず最初の図を見ながら必要なものは何かを整理してから始めることにします。

必要なもの

  • Action
  • Reducer
  • Store
  • Dispatch

Actionを作成

  • カウントアップなので、2つのActionを作成します。
  • ボタンなどをクリックしたときにこのActionが発火する。
  • DispatchからStoreに通知するときに、どのActionを通知すればいいかを判断できるようにするために、Actionに名前を付ける。
index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { createStore } from "redux";

+ // Action
+ // 増やす
+ const increase = () => {
+   return {
+     type: "INCREASE", //Action名を大文字で決める(任意)
+   };
+ };

+ // 減らす
+ const decrease = () => {
+   return {
+     type: "DECREASE", //Action名を大文字で決める(任意)
+   };
+ };

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Reducerを作成

  • Reducerは引数として以前の状態とActionを受け取り、それらを組み合わせて新しい状態に更新する。
  • 初期値は0として、受け取ったAction名によってswitch文を使用して処理を分岐させる。
index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { createStore } from "redux";

// Action
// 増やす
const increase = () => {
  return {
    type: "INCREASE", //Action名を大文字で決める(任意)
  };
};
// 減らす
const decrease = () => {
  return {
    type: "DECREASE", //Action名を大文字で決める(任意)
  };
};

+ // Reducer
+ const countReducer = (state = 0, action) => {
+  switch (action.type) {
+     case "INCREASE":
+       return state + 1; //以前の状態に+1
+     case "DECREASE":
+       return state - 1; //以前の状態から-1
+    default:
+      break;
+   }
+ };

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Storeを作成

  • Storeの中にReducerを含んでいるので引数として渡す。
index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { createStore } from "redux";

// Action
// 増やすAction
const increase = () => {
  return {
    type: "INCREASE", //Action名を大文字で決める(任意)
  };
};
// 減らすAction
const decrease = () => {
  return {
    type: "DECREASE", //Action名を大文字で決める(任意)
  };
};

// Reducer
const countReducer = (state = 0, action) => {
  switch (action.type) {
    case "INCREASE":
      return state + 1; //以前の状態に+1
    case "DECREASE":
      return state - 1; //以前の状態から-1
    default:
      break;
  }
};

+ // Store
+ let store = createStore(countReducer);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Dispatchを作成

  • 作成した、2つのActionをStoreに通知する。
index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { createStore } from "redux";

// Action
// 増やす
const increase = () => {
  return {
    type: "INCREASE", //Action名を大文字で決める(任意)
  };
};
// 減らす
const decrease = () => {
  return {
    type: "DECREASE", //Action名を大文字で決める(任意)
  };
};

// Reducer
const countReducer = (state = 0, action) => {
  switch (action.type) {
    case "INCREASE":
      return state + 1; //以前の状態に+1
    case "DECREASE":
      return state - 1; //以前の状態から-1
    default:
      break;
  }
};

// Store
let store = createStore(countReducer);

+ // Dispatch
+ store.dispatch(increase());
+ store.dispatch(decrease());

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

コンソールログで確認してみます。

  • subscribe()を使用して、新しい状態をログに出力する。
index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { createStore } from "redux";

// Action
// 増やすアクション
const increase = () => {
  return {
    type: "INCREASE", //Action名を大文字で決める(任意)
  };
};
// 減らすAction
const decrease = () => {
  return {
    type: "DECREASE", //Action名を大文字で決める(任意)
  };
};

// Reducer
const countReducer = (state = 0, action) => {
  switch (action.type) {
    case "INCREASE":
      return state + 1; //以前の状態に+1
    case "DECREASE":
      return state + 1; //以前の状態から-1
    default:
      break;
  }
};

// Store
let store = createStore(countReducer);

+ store.subscribe(() => console.log(store.getState()));

// Dispatch
store.dispatch(increase());

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

ログに出力されていることが確認されました!👏

まとめ

なかなかReduxの仕組みが理解しづらかったのですが、図を確認しながら整理することによってイメージすることができました。
基本的なことですが、ここからもっと深く学んでいきたいと思います!💪

Discussion

ログインするとコメントできます