Store, Actions, Reducers & Selectors
Redux for Angular, Built on RxJS
NgRx brings Redux's unidirectional data flow to Angular: one centralized, immutable state tree (the Store) that the whole app reads from, updated only through dispatched actions — built on RxJS observables, which Angular already relies on.
Actions & Pure Reducers
export const increment = createAction('[Counter] Increment')
export const reset = createAction('[Counter] Reset')
export const counterReducer = createReducer(
0,
on(increment, (state) => state + 1),
on(reset, () => 0)
)Actions describe an event ("increment happened") — they don't mutate anything themselves. Reducers must be pure functions that return a new state rather than mutate the existing one, because OnPush change detection and memoized selectors compare object references, not deep contents.
Memoized Selectors
export const selectItems = (state: AppState) => state.items.entities
export const selectCompletedItems = createSelector(
selectItems,
(items) => items.filter((i) => i.completed)
)Selectors decouple components from the store's shape. createSelector memoizes the result, so expensive derivations only recompute when their specific input selectors' outputs actually change by reference — not on every unrelated state change.
Consuming State in Templates
<ul>
<li *ngFor="let item of completedItems$ | async">{{ item.name }}</li>
</ul>The async pipe subscribes automatically, renders emitted values, and unsubscribes on component destroy — avoiding the common bug of a manual subscription left dangling as a memory leak.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free