State Management in Angular Using NgRx Part 1

State Management in Angular Using NgRx Pt 1

State management is a crucial aspect of building scalable and maintainable Angular applications. As your app grows in complexity, keeping track of shared application state becomes challenging. This is where state management libraries like @ngrx/store come to the rescue. In this article, we’ll explore how @ngrx/store works and how it can simplify state management in your Angular app.

What is @ngrx/store?

@ngrx/store is a state management library inspired by the Redux pattern. It provides a centralized store to manage application state, ensuring a predictable and consistent flow of data throughout your application.

Dispatch
Updates State
Notifies Changes
Display Data
Action
Reducer
Store
Component

Core Concepts

Before diving into the implementation, let’s understand the core concepts of @ngrx/store:

Store

The store is the single source of truth for your application state. It holds the entire state of your app in a single JavaScript object. Components access the state through the store and dispatch actions to modify the state.

Actions

(ads)

Actions are payloads of information that describe what happened in your application. They are simple objects with a type property that describes the action’s purpose. For instance, an action to increment a counter might have the type INCREMENT, and an action to decrement it might have the type DECREMENT.

Reducers

Reducers are pure functions responsible for transforming the state based on dispatched actions. They take the current state and an action as input and return a new state. Reducers are responsible for maintaining immutability, so they always return new objects instead of modifying the existing state.

Dispatches
Sends to
Returns
Notifies
Component
Action
Reducer
New State

Setting Up @ngrx/store

Step 1: Install Dependencies

First, let’s install the required packages using npm or yarn:

npm install @ngrx/store @ngrx/store-devtools --save
 or
yarn add @ngrx/store @ngrx/store-devtools

Step 2: Create the AppState and Reducer

Next, we’ll create the AppState interface to define the structure of our state and the reducer to handle state updates:

counter.reducer.ts

import { createReducer, on } from '@ngrx/store';
import { increment, decrement } from './counter.actions';

export interface CounterState {
  count: number;
}

export const initialState: CounterState = {
  count: 0,
};

const _counterReducer = createReducer(
  initialState,
  on(increment, (state) => ({ ...state, count: state.count + 1 })),
  on(decrement, (state) => ({ ...state, count: state.count - 1 }))
);

export function counterReducer(state: CounterState | undefined, action: Action) {
  return _counterReducer(state, action);
}

Step 3: Dispatch Actions

In your components, you can now dispatch actions to modify the state:

counter.actions.ts

import { createAction } from '@ngrx/store';

export const increment = createAction('[Counter] Increment');
export const decrement = createAction('[Counter] Decrement');

counter-control.component.ts

import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { increment, decrement } from '../counter.actions';
import { CounterState } from '../counter.reducer';

@Component({
  selector: 'app-counter-control',
  template: `
    <button (click)="increment()">Increment</button>
    <button (click)="decrement()">Decrement</button>
  `,
})
export class CounterControlComponent {
  constructor(private store: Store<CounterState>) {}

  increment(): void {
    this.store.dispatch(increment());
  }

  decrement(): void {
    this.store.dispatch(decrement());
  }
}
(ads)

Step 4: Select Data from the Store

To display the state in a component, use the async pipe with the store.select() method:

counter-display.component.ts

import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '../counter.reducer';

@Component({
  selector: 'app-counter-display',
  template: '<p>Counter Value: {{ counterValue$ | async }}</p>',
})
export class CounterDisplayComponent {
  counterValue$ = this.store.select((state) => state.count);

  constructor(private store: Store<AppState>) {}
}

Conclusion

@ngrx/store is a powerful state management solution for Angular applications. It provides a clear structure and a single source of truth for your app’s state, making it easier to manage and debug your application. By following the Redux pattern, @ngrx/store helps you maintain a consistent flow of data and actions in your app.

Demo

(getCard) #type=(custom) #title=( Managing State in Angular Apps with NgRx - Part 2: Using HTTP and Effects)
In this article, we learned about the core concepts of @ngrx/store, how to set it up, and how to use it to manage state in Angular components. By incorporating @ngrx/store into your app, you can build scalable and maintainable Angular applications that are easier to reason about and extend.

Next Post Previous Post
No Comment
Add Comment
comment url