Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Advanced NgRx for Enterprise

1. Introduction

NgRx is a state management library for Angular applications, inspired by Redux. It provides a powerful way to manage state across your application, enabling predictable state transitions and improved performance.

2. Key Concepts

2.1 Store

The Store is a centralized state management solution. It holds the state of your application and allows components to read from and write to it.

2.2 Actions

Actions are payloads of information that send data from your application to the store. They are represented as objects with a type property and optional payload.

2.3 Reducers

Reducers are pure functions that take the current state and an action as arguments, returning a new state. They specify how the state changes in response to actions.

2.4 Effects

Effects handle side effects in your application. They listen for actions dispatched from Store and perform tasks like HTTP requests or routing.

2.5 Selectors

Selectors are pure functions used to obtain slices of state from the store. They help to encapsulate the logic of accessing the state.

3. Store Setup

Setting up the store involves defining the application's state and configuring the store in your module.

import { StoreModule } from '@ngrx/store';
import { myReducer } from './reducers';

@NgModule({
  imports: [
    StoreModule.forRoot({ myState: myReducer }),
  ],
})
export class AppModule {}

4. Actions and Reducers

4.1 Defining Actions

Actions can be defined using the createAction function:

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

export const loadItems = createAction('[Items] Load Items');
export const loadItemsSuccess = createAction('[Items] Load Items Success', props<{ items: Item[] }>());

4.2 Creating Reducers

Reducers can be created using the createReducer function:

import { createReducer, on } from '@ngrx/store';
import { loadItemsSuccess } from './actions';

export const initialState = { items: [] };

const myReducer = createReducer(
  initialState,
  on(loadItemsSuccess, (state, { items }) => ({ ...state, items }))
);

5. Effects

Effects can be set up to handle asynchronous operations:

import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { MyService } from './my.service';
import { loadItems, loadItemsSuccess } from './actions';
import { switchMap } from 'rxjs/operators';

@Injectable()
export class MyEffects {
  constructor(private actions$: Actions, private myService: MyService) {}

  loadItems$ = createEffect(() =>
    this.actions$.pipe(
      ofType(loadItems),
      switchMap(() => this.myService.getItems().pipe(
        map(items => loadItemsSuccess({ items })),
      )),
    )
  );
}

6. Selectors

Selectors can be defined to obtain specific slices of state:

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

export const selectItems = (state) => state.myState.items;

export const selectItemCount = createSelector(
  selectItems,
  (items) => items.length
);

7. Best Practices

  • Use feature modules to organize your state management.
  • Leverage selectors for performance and reusability.
  • Keep actions simple and descriptive.
  • Utilize effects for handling side effects.
  • Test reducers and effects thoroughly.

8. FAQ

What is NgRx?

NgRx is a library for managing state in Angular applications, using the Redux pattern.

What are the benefits of using NgRx?

NgRx provides a predictable state container, improved performance, and easier debugging.

How do actions and reducers work together?

Actions describe state changes, while reducers specify how the state is updated based on those actions.