1. パッケージのインストール
npm install @reduxjs/toolkit react-redux
2. ディレクトリ構造の作成
次に、プロジェクトのディレクトリ構造を設定します。ここでは、状態管理に関連するファイルを src/store
に、カスタムフックを src/hooks
に配置します。
src/
├── store/ # Reduxの状態管理関連
│ ├── store.ts # ストア設定
│ └── slices/ # 機能ごとのスライス
│ └── userSlice.ts
└── hooks/ # カスタムフック
└── useRedux.ts
3. スライスの作成
Reduxのスライスは、状態とその状態を変更するためのアクションを一緒に管理します。この例では、ユーザー情報を扱うスライスを作成します。
src/store/slices/userSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
type UserState = {
userInfo: { isAdmin: boolean } | null; // ユーザー情報の型
};
const initialState: UserState = {
userInfo: null, // 初期状態
};
export const userSlice = createSlice({
name: "user",
initialState,
reducers: {
setUserInfo: (state, action: PayloadAction<{ isAdmin: boolean }>) => {
state.userInfo = action.payload; // ユーザー情報を更新
},
},
});
export const { setUserInfo } = userSlice.actions; // アクションをエクスポート
export default userSlice.reducer; // リデューサーをエクスポート
4. ストアの設定
ストアは、アプリケーションの状態を管理する中心的な部分です。以下のコードでストアを設定します。
src/store/store.ts
import { configureStore } from "@reduxjs/toolkit";
import userReducer from "./slices/userSlice";
export const store = configureStore({
reducer: {
user: userReducer, // userスライスをストアに追加
},
});
export type RootState = ReturnType<typeof store.getState>; // RootStateの型定義
export type AppDispatch = typeof store.dispatch; // AppDispatchの型定義
5. 型付きフックの作成
TypeScriptを使用することで、型安全な状態管理が可能になります。カスタムフックを作成し、型を強化します。
src/hooks/useRedux.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "../store/store";
export const useAppDispatch: () => AppDispatch = useDispatch; // 型付きdispatchフック
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; // 型付きselectorフック
6. Providerの設定
Reduxのストアをアプリケーション全体で利用できるように、Provider
コンポーネントを使用して、ストアをラップします。
src/App.tsx
import { Router } from "./router/Router"; // ルーターのインポート
import "./App.css"; // スタイルシートのインポート
import { Provider } from "react-redux"; // Providerのインポート
import { store } from "./store/store"; // ストアのインポート
function App() {
return (
<Provider store={store}> // ストアをProviderでラップ
<Router />
</Provider>
);
}
export default App;
7. コンポーネントでの使用例
状態の参照やアクションのディスパッチを行う際に、作成したカスタムフックを使用します。
状態の参照
const userInfo = useAppSelector((state) => state.user.userInfo); // ユーザー情報を取得
アクションのディスパッチ
const dispatch = useAppDispatch();
dispatch(setUserInfo({ isAdmin: true })); // アクションをディスパッチ
実装例
以下は、ユーザータイプを選択するためのコンポーネントの実装例です。
src/components/pages/Top.tsx
import styled from "styled-components"; // styled-componentsのインポート
import { DefaultLayout } from "../templates/DefaultLayout"; // レイアウトのインポート
import { SecondaryButton } from "../atoms/button/SecondaryButton"; // ボタンのインポート
import { useNavigate } from "react-router-dom"; // ルーティングのインポート
import { useAppDispatch } from "../../hooks/useRedux"; // カスタムフックのインポート
import { setUserInfo } from "../../store/slices/userSlice"; // アクションのインポート
export const Top = () => {
const navigate = useNavigate(); // ナビゲーションフックの取得
const dispatch = useAppDispatch(); // dispatchフックの取得
const onClickAdmin = () => {
dispatch(setUserInfo({ isAdmin: true })); // 管理者としてユーザー情報を設定
navigate("/users"); // ユーザー一覧ページへ遷移
};
const onClickGeneral = () => {
dispatch(setUserInfo({ isAdmin: false })); // 一般ユーザーとしてユーザー情報を設定
navigate("/users"); // ユーザー一覧ページへ遷移
};
return (
<DefaultLayout>
<SContainer>
<h2>TOP Page</h2>
<SecondaryButton onClick={onClickAdmin}>管理者</SecondaryButton>
<br />
<br />
<SecondaryButton onClick={onClickGeneral}>一般ユーザー</SecondaryButton>
</SContainer>
</DefaultLayout>
);
};
const SContainer = styled.div`
text-align: center; // 中央揃え
`;
このコンポーネントでは、管理者ボタンと一般ユーザーボタンをクリックすることで、ユーザーの状態を更新し、次のページへ遷移します。これにより、アプリケーションの動的なユーザー管理が可能になります。