Reduxは、Dan Abramovが2015年に作成したJavaScriptアプリケーションのための予測可能な状態管理コンテナです。ReduxはFluxアーキテクチャに基づく単一方向データフローを実装しています。状態は単一のStoreに保存され、純粋なReducer関数によってのみ変更され、Dispatchを伴うActionによって開始されます。npm Trendsによると、Reduxは毎週700万以上のダウンロードを維持しており、React NativeおよびWebアプリケーションにおける状態管理の標準であり続けています。
重要ポイント
Reduxは、3つの原則に基づくアーキテクチャパターンおよび状態管理ライブラリです。唯一の真実源、読み取り専用の状態、そして純粋関数による変更。モデルが予測不能に状態を変更できるMVCとは異なり、Reduxは決定論を保証します。同じ入力データに対して結果は常に同じです。
ReduxはFacebookのFluxアーキテクチャとElm言語に触発されました。Fluxとの主な違いは、複数のStoreではなく単一のStoreを使用することです。Reduxでは、アプリケーションのすべての状態(オブジェクト、配列、ローディングフラグ)が1つのツリーに保存されます。これにより、デバッグ、テスト、タイムトラベルデバッグが簡素化されます。開発者はStore全体を保存し、Actionのシーケンスを再生して、各ステップで状態がどのように変化したかを確認できます。
State of JS 2025の調査によると、状態管理を使用する回答者の68%がReduxまたはRedux Toolkitを選択しています。このツールは、React、React Native、Angular、Vue、さらにはフレームワークなしのバニラJavaScriptなど、すべての最新フレームワークでサポートされています。
単一方向データフローはReduxの重要な原則であり、データは厳密に1つの方向に移動します:View → Action → Dispatch → Reducer → Store → View。どのコンポーネントもStoreを直接変更できません。ViewはuseSelectorまたはconnectを介して変更を購読し、dispatchを介して変更を開始します。
Reduxのワークフローサイクル:ユーザーがボタンをクリック → コンポーネントがdispatch({ type: 'INCREMENT' })を呼び出す → StoreがActionをRoot Reducerに渡す → Reducerが新しい状態を計算 → Storeが購読者に通知 → Viewが新しいデータで再レンダリング。このサイクルにより、各変更には特定のActionという形で明示的な原因があることが保証されます。
DevTools — すべてのAction、Storeの状態、実行時間を監視するためのRedux組み込みツール。開発者は、ディスパッチされたすべてのActionのリスト、変更前後の状態の差分(diff)を表示し、任意の以前の状態にロールバックできます。これにより、複雑な状態のデバッグが従来のロギングと比較して数十倍高速になります。
Store — アプリケーションの完全な状態ツリーを含むオブジェクト。configureStore(RTK)またはcreateStoreを介して作成されます。Storeは3つのメソッドを提供します:getState()(読み取り)、dispatch(action)(変更)、subscribe(listener)(購読)。Redux Toolkitでは、Storeにすでにmiddleware、DevTools、スライスサポートが含まれています。
import { configureStore } from '@reduxjs/toolkit'
interface CounterState {
value: number
}
const initialState: CounterState = { value: 0 }
function counterReducer(
state = initialState,
action: { type: string }
): CounterState {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + 1 }
default:
return state
}
}
const store = configureStore({ reducer: counterReducer })
store.dispatch({ type: 'INCREMENT' })
console.log(store.getState()) // { value: 1 }ActionとAction Creator — Actionは必須のtypeフィールド(文字列定数)とオプションのpayload(データ)を持つオブジェクトです。Action CreatorはActionを返す関数です。Redux Toolkitでは、自動型付けでActionを生成するためにcreateActionが使用されます。
Reducer — 現在の状態とActionを受け取り、新しい状態を返す純粋関数。Reducerは、状態のミューテーション(新しいオブジェクトが返される)、APIの呼び出し、乱数の生成、Dateへのアクセスを行ってはいけません。不変性はスプレッド演算子...またはImmer(RTKに組み込み)によって保証されます。
| コンポーネント | 責任 | 制約 |
|---|---|---|
| Store | 状態の保存、dispatch、subscribe | アプリケーションに1つ |
| Action | 状態変更の意図の記述 | typeが必要 |
| Reducer | 新しい状態の計算 | 純粋関数、副作用なし |
| Dispatch | ActionをReducerに送信 | デフォルトで同期的 |
| Selector | Storeからデータを抽出 | createSelectorによるメモ化 |
Middlewareは、dispatch呼び出しとActionがReducerに到達するまでの間に挿入される関数のチェーンです。各middlewareはStore APIを受け取り、Actionのログ記録、変更、遅延、またはキャンセルを行うことができます。Redux Thunkは非同期操作用の標準的なmiddlewareであり、オブジェクトの代わりに関数をディスパッチできます。
import { createAsyncThunk } from '@reduxjs/toolkit'
export const fetchUser = createAsyncThunk(
'users/fetchById',
async (userId: number, { rejectWithValue }) => {
const response = await fetch(`/api/users/${userId}`)
if (!response.ok)
return rejectWithValue('Failed to fetch')
return await response.json()
}
)人気のMiddleware: Redux Thunk — 単純な非同期呼び出し用、Redux Saga — ジェネレーターサーガを使用した複雑なシナリオ用(デバウンス、レース、並列リクエスト)、Redux Observable — リアクティブストリーム用のRxJSベース。Redux Toolkitでは、middlewareはconfigureStoreのmiddlewareパラメータを介して接続されます。
State of JS 2025の調査によると、ThunkはReduxプロジェクトの72%、Sagaは18%、Observableは5%で使用されています。ほとんどのアプリケーションでは、Thunk + RTK Queryの組み合わせで非同期データワークフローの95%をカバーするのに十分です。
Redux Toolkit(RTK)は、2019年にリリースされたReduxロジックを記述する公式の推奨方法です。RTKにはconfigureStore、createSlice、createAsyncThunk、createEntityAdapterが含まれており、Reduxのボイラープレートを60〜70%削減します。Action Creator、Reducer、型を手動で作成する代わりに、単一のcreateSliceが使用されます。
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment(state) { state.value += 1 },
incrementByAmount(state, action: PayloadAction<number>) {
state.value += action.payload
}
}
})
export const { increment, incrementByAmount } = counterSlice.actions
export default counterSlice.reducerRTK Queryは、Redux Toolkitに基づくAPI操作用の組み込みソリューションです。createApiを介してエンドポイントを宣言的に定義でき、自動フック生成、キャッシング、タグ無効化、楽観的更新を提供します。RTK Queryは、APIリクエストごとに手動でThunk、Reducer、Selectorを記述する作業を置き換えます。
Entity Adapter — エンティティコレクションを正規化するためのcreateEntityAdapterユーティリティ。オブジェクト配列用の組み込みCRUDリデューサー、セレクター、ソートを提供します。Storeにユーザー、製品、注文のリストが含まれている場合、Entity Adapterはリデューサーコードを80%削減します。
React Native Reduxは、JavaScriptモバイルアプリケーションの標準スタックです。Reduxはreact-reduxのProviderを介して統合され、ルートアプリケーションコンポーネントをラップします。useSelectorフックとuseDispatchフックは、props drillingなしでコンポーネントに状態へのアクセスを提供します。Persist — redux-persistはStoreをAsyncStorageまたはMMKVに保存し、アプリケーション再起動後に状態を復元します。
React Native用Middleware: Flipperを介したデバッグ用のredux-flipper、ネイティブドライバーを使用したリアクティブストリーム用のredux-observable、高速永続ストレージ用のreact-native-mmkv。ナビゲーションプラグインredux-first-routerは画面をStoreに接続し、戻ったときに画面の状態を復元できます。
React Nativeでは、Reduxはnetwork-first戦略とともに使用されます。アプリは最初にサーバーからデータをロードしようとし、次にRTK Queryまたはredux-persistを介してStoreにキャッシュします。オフラインモードは、Redux + NetInfo + 接続が復元されたときに再送信するためのActionキューを組み合わせることで実現されます。
よくある質問
Reduxは、Store、DevTools、Middleware、不変状態を備えた本格的なソリューションです。Context APIは、props drillingなしでデータを渡すためのReactの組み込みメカニズムです。Contextはグローバルテーマやローカライゼーションに適していますが、Reduxは非同期操作、キャッシング、デバッグを伴う複雑な状態に適しています。大規模なアプリケーションでは、Contextは不要な再レンダリングを引き起こしますが、セレクターを使用したReduxはこの問題を解決します。
Immerは、Redux Toolkitに組み込まれた不変状態管理のためのライブラリです。Immerを使用すると、状態を直接変更しているかのようにリデューサーを記述できます:state.value += 1。内部では、Immerがプロキシオブジェクト(draft)を作成し、変更を追跡して新しい不変オブジェクトを返します。これにより、リデューサーコードの量が50%削減され、偶発的なミューテーションが排除されます。
Reduxロジックは分離してテストされます:Reducer — 純粋関数なので、異なるActionで呼び出して結果を確認するだけです。Action Creator — 返されるオブジェクトを検証します。Thunk — APIをモックし、dispatchを呼び出して、どのActionがディスパッチされたかを確認します。useSelectorを使用するコンポーネント — レンダラーでテスト用Storeを持つProviderを使用します。Redux DevToolsは、実際のセッションからActionシーケンスを再生してテストを作成するのに役立ちます。
useStateは単一コンポーネントのローカル状態に十分です:フィールドテキスト、モーダルの開閉。Reduxは、状態が多数の画面間で共有される場合、非同期同期(サーバーからのデータ)が必要な場合、アプリケーション再起動間で永続化する必要がある場合(persist)、またはタイムトラベルデバッグが必要な場合に必要です。小規模なアプリケーションではReduxは過剰です — 代わりにContext + useReducerを使用してください。
Normalizrは、ネストされたデータをフラットなStore構造に正規化するためのライブラリです。user.posts[0].commentsのような深いオブジェクトを保存する代わりに、正規化は辞書を作成します:entities.users、entities.posts、entities.comments(IDによる参照)。これにより、すべての場所で単一のエンティティを更新するのが簡単になり、セレクターが高速化されます。Redux Toolkitは複雑なモデルに対して正規化されたデータを推奨しています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。