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.