Reactにおける、Redux Toolkitの導入手順


### 1. パッケージのインストール

```bash
npm install @reduxjs/toolkit react-redux
```

### 2. ディレクトリ構造の作成
次に、プロジェクトのディレクトリ構造を設定します。ここでは、状態管理に関連するファイルを `src/store` に、カスタムフックを `src/hooks` に配置します。

```
src/
  ├── store/          # Reduxの状態管理関連
  │   ├── store.ts    # ストア設定
  │   └── slices/     # 機能ごとのスライス
  │       └── userSlice.ts
  └── hooks/          # カスタムフック
      └── useRedux.ts
```

### 3. スライスの作成
Reduxのスライスは、状態とその状態を変更するためのアクションを一緒に管理します。この例では、ユーザー情報を扱うスライスを作成します。

```typescript: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. ストアの設定
ストアは、アプリケーションの状態を管理する中心的な部分です。以下のコードでストアを設定します。

```typescript: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を使用することで、型安全な状態管理が可能になります。カスタムフックを作成し、型を強化します。

```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` コンポーネントを使用して、ストアをラップします。

```react: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. コンポーネントでの使用例
状態の参照やアクションのディスパッチを行う際に、作成したカスタムフックを使用します。

#### 状態の参照
```typescript
const userInfo = useAppSelector((state) => state.user.userInfo); // ユーザー情報を取得
```

#### アクションのディスパッチ
```typescript
const dispatch = useAppDispatch();
dispatch(setUserInfo({ isAdmin: true })); // アクションをディスパッチ
```

### 実装例
以下は、ユーザータイプを選択するためのコンポーネントの実装例です。

```react: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; // 中央揃え
`;
```

このコンポーネントでは、管理者ボタンと一般ユーザーボタンをクリックすることで、ユーザーの状態を更新し、次のページへ遷移します。これにより、アプリケーションの動的なユーザー管理が可能になります。