Reactアプリケーションで大規模な状態管理を行う際、Reduxは強力な選択肢となります。ここでは、Reduxの基本的な構成要素であるStore、Reducer、Actionを利用し、カウンター機能を実装する具体的な手順を解説します。
1. 依存関係の導入
プロジェクトにReduxおよびReactとの接続ライブラリを追加します。
npm install redux react-redux
2. アクション定義 (Actions)
アプリの状態変化を表すアクションオブジェクトを作成するための関数を定義します。ここでは、カウント値を増減させるためのアクションクリエイターを用意します。
src/features/counter/actions.js
// アクションタイプ定数
export const INCREMENT_COUNT = 'COUNTER/INCREMENT';
export const DECREMENT_COUNT = 'COUNTER/DECREMENT';
// インクリメントアクション
export function increaseValue() {
return {
type: INCREMENT_COUNT,
payload: 1 // オプションでペイロードを含めることも可能
};
}
// デクリメントアクション
export function decreaseValue() {
return {
type: DECREMENT_COUNT,
payload: -1
};
}
3. レデューサー実装 (Reducers)
純粋な関数として、現在の状態とアクションを受け取り、新しい状態を返すロジックを実装します。初期状態の定義と、switch文による分岐処理が中心となります。
src/features/counter/reducer.js
import { INCREMENT_COUNT, DECREMENT_COUNT } from './actions';
// アプリケーションの初期状態
const initialState = {
total: 0
};
/**
* カウンター用のレデューサー
*/
export default function counterReducer(state = initialState, action) {
switch (action.type) {
case INCREMENT_COUNT:
return {
...state,
total: state.total + 1
};
case DECREMENT_COUNT:
return {
...state,
total: state.total - 1
};
default:
return state;
}
}
4. ストアの作成 (Store Setup)
Reduxストアをインスタンス化し、上記で定義したレデューサーを登録します。
src/store/index.js
import { createStore } from 'redux';
import counterReducer from '../features/counter/reducer';
// レデューサーを組み合わせてストアを作成
const store = createStore(counterReducer);
export default store;
5. コンポーネントへの統合
Reactコンポーネント内でReduxの状態を読み取り、ディスパッチを通じて更新を行います。useSelectorフックで状態を取得し、useDispatchフックでアクションを発行します。
src/components/CounterDisplay.jsx
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increaseValue, decreaseValue } from '../features/counter/actions';
function CounterDisplay() {
// Storeから'total'プロパティを選択
const currentCount = useSelector((state) => state.total);
// ディスパッチャー関数の取得
const dispatch = useDispatch();
const handleIncrement = () => {
dispatch(increaseValue());
};
const handleDecrement = () => {
dispatch(decreaseValue());
};
return (
<div className="counter-container">
<h2>Current Count: {currentCount}</h2>
<button onClick={handleIncrement}>Increase</button>
<button onClick={handleDecrement}>Decrease</button>
</div>
);
}
export default CounterDisplay;
6. アプリケーションルートでのProvider設定
アプリのエントリーポイントにて、ReduxストアをReactツリー全体に提供するためにProviderコンポーネントでラップします。
src/App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import CounterDisplay from './components/CounterDisplay';
function App() {
return (
<Provider store={store}>
<div className="app">
<CounterDisplay />
</div>
</Provider>
);
}
export default App;