アプリケーションの規模が大きくなると、画面間やコンポーネント間で共有される「状態(state)」の一貫性を保つことが難しくなります。
Angularでは、Reduxパターンを採用した状態管理ライブラリ「NgRx」を使うことで、状態の見通しを良くし、保守性とテスト性を高めることが可能です。
本章では、NgRxの構成要素(Store、Action、Reducer、Effect)と開発補助ツール(NgRx DevTools)について学びます。

1. 状態管理の必要性
状態とは、アプリケーション内で保持すべきデータのことです。
たとえば次のような場面で状態管理が重要になります:
- ログインユーザー情報を複数画面で共有したい
- APIで取得した商品一覧を別のページでも再利用したい
- コンポーネントをまたいだイベント結果(例:お気に入り登録)を同期させたい
これらを個別のサービスやInput/Outputだけで処理するのは限界があります。
NgRxを導入することで、状態を「1か所で集中管理」し、どのコンポーネントでも安全に参照・更新できるようになります。
2. NgRxの基本構成
NgRxは、Flux/ReduxのアーキテクチャをAngularに最適化したもので、以下の要素で構成されています:
- Store: 状態(State)を一元管理するオブジェクト
- Action: 状態に対して「何をするか」を表す命令
- Reducer: Actionを受けて、状態をどう変えるかを定義
- Effect: 非同期処理(API通信など)を行う場所
■ インストール
ng add @ngrx/store
ng add @ngrx/effects
ng add @ngrx/store-devtools
■ Storeの作成(例:カウント)
src/app/store/counter.actions.ts
:
import { createAction } from '@ngrx/store';
export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');
export const reset = createAction('[Counter] Reset');
src/app/store/counter.reducer.ts
:
import { createReducer, on } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';
export const initialState = 0;
export const counterReducer = createReducer(
initialState,
on(increment, state => state + 1),
on(decrement, state => state - 1),
on(reset, state => 0)
);
app.module.ts
への登録:
import { StoreModule } from '@ngrx/store';
import { counterReducer } from './store/counter.reducer';
@NgModule({
imports: [
StoreModule.forRoot({ count: counterReducer })
]
})
■ コンポーネントからの使用
import { Store } from '@ngrx/store';
import { increment, decrement, reset } from './store/counter.actions';
constructor(private store: Store<{ count: number }>) {}
this.store.dispatch(increment());
this.store.select('count').subscribe(count => console.log(count));
3. Effectで非同期処理を管理
API通信などの副作用処理はReducerに書かず、Effectに記述します。
EffectはActionの発火をトリガーに、Observableベースで処理を行い、成功/失敗の結果を別のActionとして返すのが基本です。
■ Effectの作成例
ng generate effect store/item
@Effect() loadItems$ = createEffect(() =>
this.actions$.pipe(
ofType(loadItems),
switchMap(() => this.api.getItems().pipe(
map(items => loadItemsSuccess({ items })),
catchError(error => of(loadItemsFailure({ error })))
))
)
);
4. NgRx DevToolsの利用
NgRx DevToolsを使うことで、Actionの履歴・状態の遷移をリアルタイムで可視化できます。
Redux DevTools Extension(Chrome拡張)と連携させることで、状態のデバッグが非常に効率化されます。
StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: environment.production })
開発中に「状態がいつ・どのActionで・どう変化したか」を追えるため、実運用においても大きなメリットがあります。
まとめ
NgRxはAngularアプリの状態管理に最適なライブラリで、Action → Reducer → Store → Viewという明確な流れで、状態の一貫性と予測性を確保できます。
非同期処理はEffectに分離され、責任の分担が明確になるため、大規模なアプリやチーム開発での必須スキルです。