What is Effect in NgRx: Explanation and Example
Effect is a way to handle side effects like API calls or asynchronous tasks outside of components and reducers. It listens for specific actions and performs tasks, then dispatches new actions with results to update the state.How It Works
Think of an Effect as a helper that watches for certain signals (actions) in your app. When it sees a signal, it does some work like fetching data from a server or saving something, then sends back a new signal with the result.
This keeps your app organized by separating the side tasks from the main logic that changes the state. It’s like having a friend who handles errands for you when you ask, so you can focus on other things.
Example
This example shows an Effect that listens for a loadItems action, calls a fake API service to get items, and then dispatches a loadItemsSuccess action with the data.
import { Injectable } from '@angular/core'; import { createEffect, ofType, Actions } from '@ngrx/effects'; import { of } from 'rxjs'; import { catchError, map, mergeMap } from 'rxjs/operators'; import * as ItemActions from './item.actions'; import { ItemService } from './item.service'; @Injectable() export class ItemEffects { loadItems$ = createEffect(() => this.actions$.pipe( ofType(ItemActions.loadItems), mergeMap(() => this.itemService.getItems().pipe( map(items => ItemActions.loadItemsSuccess({ items })), catchError(() => of(ItemActions.loadItemsFailure())) ) ) ) ); constructor(private actions$: Actions, private itemService: ItemService) {} } // item.actions.ts import { createAction, props } from '@ngrx/store'; export const loadItems = createAction('[Item] Load Items'); export const loadItemsSuccess = createAction( '[Item] Load Items Success', props<{ items: string[] }>() ); export const loadItemsFailure = createAction('[Item] Load Items Failure'); // item.service.ts export class ItemService { getItems() { return of(['Apple', 'Banana', 'Cherry']); // Simulated API call } }
When to Use
Use Effects when you need to do tasks that don't directly change the state but affect it later, like:
- Fetching or saving data from a server
- Calling external APIs
- Performing asynchronous operations
- Triggering multiple actions based on one event
This keeps your state management clean and your components simple, focusing only on displaying data and user interaction.
Key Points
- Effects listen for actions and perform side effects.
- They keep side tasks separate from state changes.
- Use RxJS operators to handle async work inside effects.
- Effects dispatch new actions with results to update the store.
- They help keep components and reducers simple and focused.