LoginSignup
2
1

More than 1 year has passed since last update.

グローバルステートの管理にはReduxを使おう(仕組み〜簡単な実装まで)

Posted at

◆ 目次

・はじめに(Reduxとは)

・Reduxの管理の仕組み

・定義方法

・実践してみよう



◆ はじめに(reduxとは)

Reduxとは、Reactとは別でグローバルステートを管理するライブラリ。


【 グローバルステート 】
アプリケーション全体で管理するステート。ReactでいうuseContext。

【 ローカルステート 】
特定のコンテキスト内のみで管理するステート。ReactでいうuseState。

◆ Reduxの管理の仕組み

・Store

スクリーンショット 2023-03-25 15.45.51.png

Reduxのデータの保存場所。
状態を保管するステートと、ステートを更新する関数(Reducer)を持っている。

・Disptach

スクリーンショット 2023-03-25 15.54.44.png

Reducerを呼び出すために実行する関数。
Dispatchを呼び出すことでReducerが実行され、ステートが更新される。

・全体的な流れ

スクリーンショット 2023-03-25 15.59.00.png

① 初期値のステートがUIに表示される。Dispatchを実行するためのイベントをUIで実行する。

② Dispatchを実行したことでReducerが呼び出される。ステートが更新される。

③ 更新されたステートが画面に表示される。

◆ 定義方法

・更新関数の定義

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

const Example = createSlice({
  // Sliceの名前
  name: 'example',
  // ステートの初期値 ※プロパティ名は任意
  initialState: 0,
  // 更新関数をオブジェクトで定義
  reducers: {
  // 定義したいメソッドを記載
  }
})

// アクションクリエイターの定義
const { /* 定義したメソッド */ } = example.actions;
/*
 * 【アクションクリエイター】
 * Dispatch(更新関数を呼び出す関数)の引数に指定する※Actionを定義する関数のこと
 * createSliceでは、アクションクリエイターが自動で作成される。
 */

export { /* アクションクリエイター名 */ }
export default example.reducer;

※Actionとは

Actionとは、ユーザーが行なった操作をオブジェクトで表現したものと考えれば良い。

Action : {
  type: "アクションの種類",
  payload: "アクション時に利用するデータ"
}


・Storeの定義

import { reducer } from "更新関数を定義したファイルの階層"
import { configureStore } from "@reduxjs/toolkit"

export default configureStore({
  reducer: {
    // 先ほど定義した更新関数をオブジェクト内に定義 ※プロパティ名は任意
    example: reducer
  }
});

・Dispatchの取得

import { useDispatch } from "react-redux";

const Example = () => {
  const dispatch = useDispatch();
}

・ステートの取得

import { useSelector } from "react-redux";

const Example = () => {
  const state = useSelector(state => state);
}

/*
 * useSlector
 * 
 * 引数にはコールバック関数を定義する。
 * コールバック関数の引数のstateは、Reduxで現在管理しているState(グローバルステート)を表している。
 * 今回のExampleコンポーネントでは、管理しているStateをそのまま出力している。
 */

・Storeへのアクセス

import { Provider } from "react-redux";
import store from "configureStoreを用いてStoreを定義したファイルの階層"

const App = () => {
  return (
    <Provider store={store}>
      {/* Storeへのアクセスを可能にしたいコンポーネントをchildrenに設定 */}
      <Example></Example>
    </Provider>
  )
}

◆ 実践してみよう

スクリーンショット 2023-03-26 15.35.30.png

ボタンを押すとボタンに書かれた数字分、表示された数字が加減されるものを作成します。

①更新関数の定義

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

const counter = createSlice({
  // Sliceの名前
  name: 'counter',
  // 初期値の値
  initialState: 0,
  // 更新関数の定義
  reducers: {
  // プラスの時のメソッド
    add(state, {type, payload}) {
      return state + payload;
    },
  // マイナスの時のメソッド
    minus(state, {type, payload}) {
      return state - payload;
    }
  }
})

// アクションクリエイターの定義
const { add, minus } = counter.actions

// アクションクリエイターとReducerのexport
export { add, minus }
export default counter.reducer;

②Storeの定義

import { reducer } from "reducerを定義したファイルの階層"
import { configureStore } from "@reduxjs/toolkit"

export default configureStore({
  reducer: {
    counter: reducer
  }
});

③ボタンコンポーネントの作成

import { add, minus } from "アクションクリエイターを定義したファイルの階層";
import { useDispatch } from "react-redux";

const CounterButton = ({ calcType, step }) => {
  // dispatchの取得
  const dispatch = useDispatch();
  // dispatch呼び出し用のイベントハンドラの定義
  const clickhandler = () => {
  // アクションクリエイター(calctTypeの値に応じて条件分岐)
  // アクションクリエイターによって作成したActionを引数に格納し、dispatchの引数に指定して実行 
    const action = calcType === "+" ? add(step) : minus(step); 
    dispatch(action);
  }

  return (
    <button onClick={clickHandler}>{calcType}{step}</button>
  )
}

export default CounterButton;

④表示用のコンポーネントの作成

import { useSelector } from "react-redux";

const CounterResult = () => {
  // ステートの取得
  const state = useSelector(state => state);

  return (
    <p>{state}</p>
  )
}
export default CounterResult;

⑤画面表示

・App.js

import { Provider } from "react-redux";
import store  from "storeを定義したファイルの階層";
import CounterButton from "定義したファイルの階層";
import CounterResult from "定義したファイルの階層";

const App = () => {
  return (
    <>
      <Provider store={store}>
        <CounterResult />
        <CounterButton calcType={"+"} step={2}/>
        <CounterButton calcType={"-"} step={2}/>
        <CounterButton calcType={"+"} step={10}/>
        <CounterButton calcType={"-"} step={10}/>
      </Provider>
    </>
  )
}

以上で完成です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1