いずみこんな悩みを解決できる記事を書きました!
僕は現役フリーランスエンジニア(歴10年)で、資格は13個保有しています。
「AngularでNgRxを使った状態管理を実装する方法を知りたい」とお考えではありませんか?
Angularアプリの規模が大きくなり、コンポーネント間で状態を共有する処理が複雑になってきた方へ。
NgRxを使えば、アプリ全体の状態を1つのStoreにまとめて管理することが可能です。



サクッと解説します。
ということで、本記事ではAngularでNgRxを使った状態管理を実装する方法を解説します。



すぐ読み終わるので、ぜひ最後まで読んでくださいませ。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【Angular】NgRxで状態管理を実装する方法
早速ですが、AngularでNgRxを使った状態管理の実装方法を解説します。
NgRxとは
NgRxはReduxパターンをAngular向けに実装した状態管理ライブラリです。
Action・Reducer・Store・Selectorという4つの要素で構成されています。
コンポーネントがActionをdispatchすると、Reducerが新しい状態を計算してStoreを更新します。
コンポーネントはSelectorを通してStoreから必要な状態だけを取得します。



Reduxを触ったことがある方なら、考え方はほぼ同じなので理解しやすいと思います。
NgRxをインストールする
まずは、NgRxをインストールします。
npmコマンドで@ngrx/store・@ngrx/effects・@ngrx/store-devtoolsをインストールします。
npm install @ngrx/store @ngrx/effects @ngrx/store-devtoolsprovideStoreをapp.config.tsのprovidersに追加します。
import { ApplicationConfig } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { provideEffects } from '@ngrx/effects';
import { provideStoreDevtools } from '@ngrx/store-devtools';
export const appConfig: ApplicationConfig = {
providers: [
provideStore(),
provideEffects(),
provideStoreDevtools({ maxAge: 25 }),
],
};provideStoreDevtoolsを追加しておくと、ブラウザ拡張機能のNgRx DevToolsで状態の変化を確認できます。
Actionを定義する
次に、状態を変更するきっかけとなるActionを定義します。
createActionGroupを使うと、関連するActionをまとめて1つのオブジェクトとして定義できます。
import { createActionGroup, emptyProps, props } from '@ngrx/store';
import { Todo } from './todo.model';
export const TodosActions = createActionGroup({
source: 'Todos',
events: {
'Load Todos': emptyProps(),
'Load Todos Success': props<{ todos: Todo[] }>(),
'Load Todos Failure': props<{ error: string }>(),
'Add Todo': props<{ title: string }>(),
},
});


イベント名を文字列で書くだけで、キャメルケースのActionクリエイターが自動生成されるので、命名の重複を防げます。
Reducerを定義する
続いて、Actionを受け取って状態を更新するReducerを定義します。
createFeatureを使うと、Reducerの定義と同時にSelectorも自動生成されます。
import { createFeature, createReducer, on } from '@ngrx/store';
import { TodosActions } from './todos.actions';
import { Todo } from './todo.model';
interface TodosState {
todos: Todo[];
loading: boolean;
error: string | null;
}
const initialState: TodosState = {
todos: [],
loading: false,
error: null,
};
export const todosFeature = createFeature({
name: 'todos',
reducer: createReducer(
initialState,
on(TodosActions.loadTodos, (state) => ({ ...state, loading: true })),
on(TodosActions.loadTodosSuccess, (state, { todos }) => ({
...state,
todos,
loading: false,
})),
on(TodosActions.loadTodosFailure, (state, { error }) => ({
...state,
error,
loading: false,
})),
on(TodosActions.addTodo, (state, { title }) => ({
...state,
todos: [...state.todos, { id: Date.now(), title, done: false }],
})),
),
});onの第1引数に対象のActionを、第2引数に状態を更新する関数を渡します。
Storeにfeatureを登録する
定義したtodosFeatureを、app.config.tsのprovidersにprovideStateで登録します。
providers: [
provideStore(),
provideState(todosFeature),
provideEffects(TodosEffects),
],provideEffectsにTodosEffectsを渡して、後述する非同期処理も同時に登録します。
コンポーネントから状態を利用する
コンポーネント側では、Storeをinjectして状態の取得とActionのdispatchを行います。
import { Component, inject } from '@angular/core';
import { Store } from '@ngrx/store';
import { todosFeature } from './todos.reducer';
import { TodosActions } from './todos.actions';
@Component({
selector: 'app-todo-list',
standalone: true,
templateUrl: './todo-list.component.html',
})
export class TodoListComponent {
private store = inject(Store);
todos = this.store.selectSignal(todosFeature.selectTodos);
loading = this.store.selectSignal(todosFeature.selectLoading);
constructor() {
this.store.dispatch(TodosActions.loadTodos());
}
addTodo(title: string) {
this.store.dispatch(TodosActions.addTodo({ title }));
}
}selectSignalを使うと、Selectorの結果をAngular Signalとしてテンプレートで直接扱えます。



selectSignalのおかげで、async pipeを使わずにテンプレート内で状態を表示できるようになりました。
非同期処理をEffectsで実装する
APIからデータを取得するような非同期処理は、Effectsに切り出します。
import { Injectable, inject } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { catchError, map, of, switchMap } from 'rxjs';
import { TodosActions } from './todos.actions';
import { TodoService } from './todo.service';
@Injectable()
export class TodosEffects {
private actions$ = inject(Actions);
private todoService = inject(TodoService);
loadTodos$ = createEffect(() =>
this.actions$.pipe(
ofType(TodosActions.loadTodos),
switchMap(() =>
this.todoService.getTodos().pipe(
map((todos) => TodosActions.loadTodosSuccess({ todos })),
catchError((error) => of(TodosActions.loadTodosFailure({ error: error.message }))),
),
),
),
);
}createEffectの中でActionを監視し、APIの結果に応じて成功または失敗のActionをdispatchします。



EffectsにAPI通信をまとめておくと、コンポーネントとReducerはAPIの存在を意識しなくて済むので、テストもしやすくなります。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【厳選】フリーランスエンジニアにおすすめなエージェント3選


フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。
僕が実際に利用しているおすすめエージェントを紹介しますね。



エージェントは必ず複数登録してください。
担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…
僕は実際に5つのエージェントを使い回していますよ。
フリーランスを始めるなら「レバテックフリーランス


」
- 業界最大級の案件数。
- 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
- 案件参画中のフォローの充実。
※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。
レバテックフリーランス
![]()
![]()
とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!



僕もはじめてフリーランスの案件を貰ったのはレバテックフリーランス
![]()
![]()
保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。
手厚い保障を重視したいなら「Midworks


」
- 手厚い保障で正社員並みの安心感。
- 還元率60%超え&単価公開でクリアな契約。
- 給与保障制度(審査あり)。
Midworks
![]()
![]()
フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。



僕も何度か案件を紹介してもらいました。
自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。
週2〜3日の案件探しなら「ITプロパートナーズ


」
- IT案件に特化したフリーランスエージェント。
- 週2〜3日の案件が豊富。
- リモート案件が多く、直エンドなので単価も高い。
※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。
ITプロパートナーズ
![]()
![]()
週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。



週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。
とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!
よくある質問
NgRxとAngular Signalsはどちらを使うべきですか?
コンポーネント単体やごく限られた範囲で完結する状態であれば、Angular Signalsだけで十分管理できます。
複数の離れたコンポーネントで同じ状態を共有したり、状態の変化履歴をNgRx DevToolsで追いたい場合は、NgRxの導入を検討すると良いです。
createActionGroupを使うメリットは何ですか?
イベント名の重複を防ぎつつ、キャメルケースのActionクリエイターを自動生成してくれます。
個別にcreateActionを書くよりもコード量が減り、関連するActionが1つのオブジェクトにまとまるので見通しも良くなります。
NgRx DevToolsは必須ですか?
必須ではありませんが、開発中に導入しておくとdispatchされたActionと状態の変化を時系列で確認できます。
provideStoreDevtoolsをapp.config.tsに追加するだけで使えるようになります。
まとめ
今回は、AngularでNgRxを使った状態管理を実装する方法について解説しました。
以下が本記事のまとめになります。
- おすすめ本
Angularの勉強なら「Angularアプリケーションプログラミング



最後までお読みいただき、ありがとうございました!
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
- クソおすすめ本



海外のエンジニアがどういった思考で働いているかが理解できます。
海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。









