DEV Community

Cover image for Basic State Management in Angular using Ngrx, inspired by Redux
Muhammad Awais
Muhammad Awais

Posted on

Basic State Management in Angular using Ngrx, inspired by Redux

What is Ngrx? ❤️

NgRx is an open source library that provides reactive state management for your Angular applications. Inspired by Redux, NgRx provides a way to maintain data in your Angular application as a single source of truth. NgRx uses streams to interact with a data store.

How NgRx works

There are five parts that constitute NgRx:

  1. Store
  2. Reducers
  3. Actions
  4. Selectors
  5. Effects

state-management-lifecycle

Key Concepts:

Pure Function: A pure function as a function that doesn’t have an internal state. It means that all operations it performs are not affected by that state and given the same input parameters and produces the same deterministic output.

  1. Store: Your application’s state is maintained in the store. The store is immutable.
  2. Reducers: Reducers are functions that take the current state and an action as arguments, and return a new state result to store. In other words, (state, action) => newState
  3. Actions: Actions are unique events that can be dispatched from a component or service.
  4. Selectors: are pure functions used to select, derive and compose pieces of state.
  5. Effects: occur as a result from actions, and can also create actions when called. Effects primary responsibility is to create async side-effects (like service calls to APIs), that ultimately generate other actions.

Let's start with a sample application to deep dive in to State Management using NgRx

👉 Create a new angular app:

ng new redux-angular-app
Enter fullscreen mode Exit fullscreen mode

👉 Install @ngrx /store npm module:

npm i @ngrx/store --save
Enter fullscreen mode Exit fullscreen mode

👉 updations in app.module

// Ngrx imports for store and newly created reducer
import { StoreModule } from '@ngrx/store';
import { simpleReducer } from './ngrx/simple.reducer';

...

imports: [
    ...
    StoreModule.forRoot({ message: simpleReducer })
],
Enter fullscreen mode Exit fullscreen mode

👉 Create a simpleReducer

import { Action } from "@ngrx/store";

export function simpleReducer(state: string = 'Hello World', action: Action) {
    console.log(action.type, state);

// updating and returning the newly state to store on the basis of dispatched action type
    switch (action.type) {
        case 'SPANISH':
            return state = 'Hola Mundo';

        case 'FRENCH':
            return state = 'Bonjour le monde';

        default:
            return state;
    }
}
Enter fullscreen mode Exit fullscreen mode

👉 NgRx/Redux in action inside the desired component

// import the store from ngrx and observable from rxjs
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';

...

interface AppState {
  message: string;
}

...

// an observable in which we get updated state from store
message$: Observable<string>

constructor(
   private store: Store<AppState>,
) {
    // retrieve data from ngrx store 
    this.message$ = this.store.select('message');
}

ngOnInit(): void {
}

// dispatching actions to reducer for further task to update the store with newly state
spanishMessage() {
    this.store.dispatch({ type: 'SPANISH' });
}

frenchMessage() {
    this.store.dispatch({ type: 'FRENCH' });
}
Enter fullscreen mode Exit fullscreen mode
<p>{{message$ | async}}</p>

<button (click)="spanishMessage()">Spanish</button>
<button (click)="frenchMessage()">French</button>
Enter fullscreen mode Exit fullscreen mode

Github: https://github.com/muhammadawaisshaikh/redux-angular-ngrx/

Happy Redux 🚀

Discussion (0)