Angularにおける状態管理(NgRxの導入)

アプリケーションの規模が大きくなると、画面間やコンポーネント間で共有される「状態(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に分離され、責任の分担が明確になるため、大規模なアプリやチーム開発での必須スキルです。

採用情報 長谷川 横バージョン
SHARE
PHP Code Snippets Powered By : XYZScripts.com