State Management with NgRx Signals Store

State Management with NgRx Signals Store

NgRx SignalStore is a lightweight state management solution built on Angular Signals — simpler than the classic NgRx Store while still providing structure for complex state.

Installation

npm install @ngrx/signals

Define a Store

// product.store.ts
import { signalStore, withState, withComputed, withMethods } from '@ngrx/signals';
import { computed, inject } from '@angular/core';
import { rxMethod } from '@ngrx/signals/rxjs-interop';
import { tapResponse } from '@ngrx/operators';
import { pipe, switchMap } from 'rxjs';

interface ProductState {
  products: Product[];
  loading:  boolean;
  error:    string | null;
  filter:   string;
}

export const ProductStore = signalStore(
  { providedIn: 'root' },

  withState<ProductState>({
    products: [],
    loading:  false,
    error:    null,
    filter:   '',
  }),

  withComputed(({ products, filter }) => ({
    filteredProducts: computed(() =>
      products().filter(p => p.name.toLowerCase().includes(filter().toLowerCase()))
    ),
    totalCount: computed(() => products().length),
  })),

  withMethods((store, productService = inject(ProductService)) => ({
    loadProducts: rxMethod<void>(
      pipe(
        tap(() => patchState(store, { loading: true })),
        switchMap(() =>
          productService.getAll().pipe(
            tapResponse({
              next:  products => patchState(store, { products, loading: false }),
              error: err     => patchState(store, { error: String(err), loading: false }),
            })
          )
        )
      )
    ),
    setFilter(filter: string): void {
      patchState(store, { filter });
    },
  }))
);

Use in Component

@Component({ /* ... */ })
export class ProductListComponent implements OnInit {
  readonly store = inject(ProductStore);

  ngOnInit(): void { this.store.loadProducts(); }
}
<input [value]="store.filter()" (input)="store.setFilter($event.target.value)" />
@for (product of store.filteredProducts(); track product.id) {
  <app-product-card [product]="product" />
}
AngularJS {"id":69,"topic_id":33,"name":"Signals and State Management","slug":"signals-and-state-management","image":null,"description":"<p>Use Angular Signals for fine-grained reactivity and NgRx for large-scale state management.<\/p>","icon":null,"class":null,"color":null,"status":0,"order":7,"created_at":"2026-05-04T21:01:53.000000Z","updated_at":"2026-05-04T21:01:53.000000Z"} - List of Contents

Related Tutorials: