Basic State Management in Angular using Ngrx, inspired by Redux ⚡️
Tags: angular, ngrx, typescript
Published: 2021-08-25 20:04:09

## 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](https://ngrx.io/generated/images/guide/store/state-management-lifecycle.png)

## 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.
3. **Selectors:** are pure functions used to select, derive and compose pieces of state.
4. **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
```

👉 Install @ngrx/store npm module:

```
npm i @ngrx/store --save
```

👉 updations in app.module

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

...

imports: [
    ...
    StoreModule.forRoot({ message: simpleReducer })
],
```

👉 Create a simpleReducer

```javascript
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;
    }
}
```

👉 NgRx/Redux in action inside the desired component

```javascript
// 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' });
}
```

```html
<p>{{message$ | async}}</p>

<button (click)="spanishMessage()">Spanish</button>
<button (click)="frenchMessage()">French</button>
```

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

## Happy Redux 🚀