🔮 はじめに
Reactの状態管理ライブラリでよく使用されるReduxについて少し勉強したため.忘備録として簡単にまとめます.
🔮 自己紹介
初めまして.趣味でweb開発を勉強している273*(ツナサンド) / Kei.と申します.関西の大学生です.最近はフルスタック開発やツール制作を行なっています.初心者です.
🔮 本題
Redux
公式ドキュメント
https://redux.js.org/
ReactのuseStateのように状態を管理するもの.useStateはコンポーネント単位でしか管理できないが,Reduxはアプリ全体で状態を管理(一元管理)するツールである.他のフレームワークでも利用可能.Redux Toolkitの使用が推奨されているので,ここではそれを使用する.
- 「グローバルストア」と呼ばれる場所で状態(state) を一括管理する.
- 状態を直接変更するのではなく,アクション(action) を通じてどう変えるかをReducerで定義する.
RecoilやZustand,Jotaiなど状態管理ライブラリは色々ある.
RecoilはReduxより簡単だが開発が止まっているため推奨しない.
Jotaiは日本人が作っている.
Redux Toolkit
公式ドキュメント
https://redux-toolkit.js.org/
Redux Toolkit とは,アプリケーションの状態管理をする Redux をより簡単に扱えるようにしたライブラリ.公式もこちらの仕様を推奨している.
基本用語
Store
- アプリ全体の状態を保持する.Reduxの中心的な存在.
- 各コンポーネントはストアから状態を取得したり,更新を依頼する.
import { configureStore } from "@reduxjs/toolkit";
const store = configureStore({
reducer: {
user: userReducer,
channel: channelReducer,
}
});
State
- ストアに保存されているデータそのもの.
- アプリ全体の「現在の状態」を表す.
const initialState: InitialChannelState = {
channelId: null,
channelName: null,
};
Action
- 状態を変更するために送る指示.Acrion Createrで生成される.
// acrionの例.JSONに似たJavaScriptオブジェクト
{
"type": "user/setName", // アクションの種類を示す
"payload": "Bob" // 必要に応じてデータを含む
}
Dispatch
- アクションをストアに送るためのメソッド.
- アクションがディスパッチされるとReducer が呼び出され,状態が更新されます。
dispatch(setName("Bob"))}
dispatch({ type: "user/setName", payload: "Bob" });
Reducer
- アクションを受け取り,新しい状態を計算する純粋関数.
- 現在の状態とアクションを引数に取り,新しい状態を返す.
reducers: {
login: (state, action) => {
state.user = action.payload;
},
logout: (state) => {
state.user = null;
},
}
Selector
- ストアから必要なデータを取り出すための関数.
- コンポーネントで
useSelector
を使ってアクセスする.
const userName = useSelector((state) => state.user.name);
Slice
- state,Reducer,action creatorをまとめたもの
// 買い物かごの初期化
const initialState = {
cartItem: [], // 商品リスト
amount: 0, // 合計個数
total: 0, // 合計金額
};
const cartSlice = createSlice({
name: "cart", // sliceの名前 useSelectorで参照するときに使う
initialState, // 初期値
reducers: {}, // action creatorが含まれている(自動生成)
});
Provider
- Storeをどのコンポーネントからも使えるようにするもの.
import { Provider } from "react-redux";
import { store } from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
動作の流れ
- ユーザが操作する.
:ボタンをクリックしたりフォームを送信したりなど,イベントをトリガーする. - Actionが生成される.
:ユーザの操作に応じてAction Creator
がアクションを生成する.
:ユーザの操作に応じて「何をしたいか(アクション)」を作るのがAcrion Creater.
// Action Createrとaction
const setName = (name) => ({
type: "user/setName",
payload: name,
});
- Dispatch でアクションをストアに送る
:アクションがdispatch
を通じてストアに送られる.
dispatch(setName("Bob"));
- Reducer が新しい状態を計算する
:ストアは Reducer を呼び出し,アクションに応じて新しい状態を計算する - ストアの状態が更新される
:新しい状態がストアに保存される - UIがレンダリングされる
イメージ
Redux Toolkitを用いた状態管理の例
- ストアの設定
import { configureStore } from "@reduxjs/toolkit";
import userReducer from "./userSlice";
// ストアの作成
const store = configureStore({
reducer: {
user: userReducer, // reducerの設定
},
});
export default store;
- スライスの作成
import { createSlice } from "@reduxjs/toolkit";
const userSlice = createSlice({
name: "user", // スライス名
initialState: { name: "Alice" }, // stateの初期値
// stateの更新処理
reducers: {
setName: (state, action) => {
state.name = action.payload;
},
},
});
// action creater を作成してエクスポート
export const { setName } = userSlice.actions;
export default userSlice.reducer;
- Reactコンポーネントで使用
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { setName } from "./userSlice";
const UserComponent = () => {
// useSelectorで現在のstateを取得
// state.userのuserはreducerで定義したオブジェクトのuserプロパティのこと
const name = useSelector((state) => state.user.name);
// 以下のようにactionをdispatchでストアに送る
const dispatch = useDispatch();
return (
<div>
<p>User Name: {name}</p>
<button onClick={() => dispatch(setName("Bob"))}>
Change Name
</button>
</div>
);
};
export default UserComponent;
🔗 参考文献
🔮 最後に
Redux / Redux-Toolkitについてまとめてみました!誰かの参考になったら幸いです.最後まで読んでいただきありがとうございました.それでは!