Reduxを使ったシンプルなカウンターアプリケーションの作成手順

# Reduxを使ったシンプルなカウンターアプリケーションの作成手順

この記事では、Reduxを使ってシンプルなカウンターアプリケーションを作成し、データを管理する方法を解説します。Reduxの特有の概念がいくつか登場するので、それらを一つひとつ解説しながら進めていきます。

## 1. Reduxとは？

Reduxは、アプリケーション全体の「状態」を一元的に管理するライブラリです。通常、Reactではコンポーネントごとに状態を管理しますが、複数のコンポーネント間で状態を共有する場合や、アプリケーションが大きくなるにつれて状態管理が複雑になることがあります。そこで、Reduxを使うと、アプリケーション全体の状態を一つの「Store」で管理し、データの変更を「Action」を通じて行います。

## 2. 環境設定と必要なパッケージのインストール

まずは、Reduxを使う準備を整えます。

```bash
npx create-react-app simple-redux-app
cd simple-redux-app
yarn add @reduxjs/toolkit react-redux react-router-dom
```

このコマンドでReactアプリケーションを作成し、ReduxとReact Routerに必要なパッケージをインストールします。

### Redux Toolkitとは？

Redux Toolkitは、Reduxの公式ツールキットで、Reduxの基本的なセットアップを簡単に行えるようにするライブラリです。従来のReduxの冗長なコードを簡素化してくれるため、初学者にも使いやすいツールです。

## 3. Reduxのセットアップ

### 3.1 カウンターのスライスを作成

ここでは、「スライス」というReduxの重要な概念が登場します。

#### スライスとは？
スライスは、Reduxの「状態」とその状態を操作するための「リデューサー」をひとまとめにしたものです。例えば、カウンターの値（状態）を増減させるための操作を一つのスライスとして定義します。

```typescript
// src/features/counter/counterSlice.ts
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
    name: 'counter',  // スライスの名前
    initialState: { value: 0 },  // 初期状態（カウンターの初期値）
    reducers: {
        increment: state => {
            state.value += 1;  // カウンターを1増やす
        },
        decrement: state => {
            state.value -= 1;  // カウンターを1減らす
        }
    }
});

// Actionのエクスポート
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
```

### 3.2 Storeの設定

次に、「Store」という概念を導入します。

#### Storeとは？
Storeは、アプリケーション全体の状態を保持する場所です。すべてのデータ（状態）はStoreに保存され、コンポーネントはこのStoreからデータを取得し、また必要に応じて更新します。

```typescript
// src/app/store.ts
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';

export const store = configureStore({
    reducer: {
        counter: counterReducer,  // カウンタースライスをStoreに登録
    },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
```

### 3.3 Providerでアプリケーションをラップ

ここでは、`Provider`という重要なコンポーネントを使います。

#### Providerとは？
Providerは、Reactコンポーネント全体にReduxのStoreを提供する役割を持つコンポーネントです。これによって、アプリケーション内のどのコンポーネントからでもStoreにアクセスできるようになります。

```typescript
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import { store } from './app/store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
```

## 4. React Routerの設定とページの作成

次に、`React Router`を使って複数のページを作成し、ページ間を移動できるようにします。

### 4.1 ルーティングの設定

```typescript
// src/App.tsx
import React from 'react';
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom';
import CounterDisplay from './features/counter/CounterDisplay';
import CounterControls from './features/counter/CounterControls';

function App() {
    return (
        <Router>
            <nav>
                <ul>
                    <li><Link to="/">カウンター表示</Link></li>
                    <li><Link to="/controls">カウンター操作</Link></li>
                </ul>
            </nav>
            <Routes>
                <Route path="/" element={<CounterDisplay />} />
                <Route path="/controls" element={<CounterControls />} />
            </Routes>
        </Router>
    );
}

export default App;
```

### 4.2 カウンターの状態を表示するページ

#### useSelectorとは？
`useSelector`は、ReduxのStoreから必要なデータを取り出すためのフックです。このフックを使って、コンポーネント内でReduxの状態を取得します。

```typescript
// src/features/counter/CounterDisplay.tsx
import React from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '../../app/store';

const CounterDisplay: React.FC = () => {
    const count = useSelector((state: RootState) => state.counter.value);  // Reduxの状態からカウンターの値を取得

    return (
        <div>
            <h1>カウンターの値: {count}</h1>
        </div>
    );
};

export default CounterDisplay;
```

### 4.3 カウンターの値を操作するページ

#### useDispatchとは？
`useDispatch`は、Reduxの「アクション」をコンポーネントから実行するためのフックです。これを使って、カウンターを増やしたり減らしたりする操作を実行します。

```typescript
// src/features/counter/CounterControls.tsx
import React from 'react';
import { useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

const CounterControls: React.FC = () => {
    const dispatch = useDispatch();  // Reduxのdispatch関数を取得

    return (
        <div>
            <button onClick={() => dispatch(increment())}>増やす</button>
            <button onClick={() => dispatch(decrement())}>減らす</button>
        </div>
    );
};

export default CounterControls;
```

## 5. まとめ

この記事では、Reduxの基本的な概念である「スライス」「Store」「アクション」などを学びつつ、非常にシンプルなカウンターアプリケーションを作成しました。Reduxを使うことで、アプリケーション全体で一元的に状態を管理できるようになります。初学者の方でも、まずはこの簡単な例から始め、徐々に複雑な状態管理に挑戦してみてください。