How to manage state in NgRx? (with examples)

In Angular applications, using NgRx for state management can help you effectively manage the application's state and data flow. The following is a simple example detailing how to use NgRx for state management.

Suppose you have a to-do list and you want to use NgRx to manage the status of this list.

Step 1: Install NgRx related packages

First, make sure you have installed @ngrx/store and @ngrx/effects related packages in your Angular project. You can install these packages using the Angular CLI or npm/yarn.

npm install @ngrx/store @ngrx/effects

Step 2: Define State

Define your state object in your app. In this example, we will create a status object containing an array of to-do items.

// app.state.ts

export interface AppState {
    
    
  todos: Todo[];
}

export interface Todo {
    
    
  id: number;
  text: string;
  completed: boolean;
}

Step 3: Create Actions

Create action objects that describe state changes. In this example, we will create actions that add, remove, and toggle the completion state.

// todo.actions.ts

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

export const addTodo = createAction('[Todo] Add Todo', props<{
      
       text: string }>());
export const deleteTodo = createAction('[Todo] Delete Todo', props<{
      
       id: number }>());
export const toggleTodo = createAction('[Todo] Toggle Todo', props<{
      
       id: number }>());

Step 4: Create Reducers

Create reducers to process actions and update state. Reducers are pure functions that intelligently handle state updates based on the current state and actions.

// todo.reducer.ts

import {
    
     createReducer, on } from '@ngrx/store';
import {
    
     addTodo, deleteTodo, toggleTodo } from './todo.actions';

export const initialState: Todo[] = [];

const _todoReducer = createReducer(
  initialState,
  on(addTodo, (state, {
    
     text }) => [...state, {
    
     id: state.length + 1, text, completed: false }]),
  on(deleteTodo, (state, {
    
     id }) => state.filter((todo) => todo.id !== id)),
  on(toggleTodo, (state, {
    
     id }) =>
    state.map((todo) => (todo.id === id ? {
    
     ...todo, completed: !todo.completed } : todo))
  )
);

export function todoReducer(state: Todo[] | undefined, action: any) {
    
    
  return _todoReducer(state, action);
}

Step 5: Configure Store

Configure the store in app.module.ts of your Angular application.

// app.module.ts

import {
    
     StoreModule } from '@ngrx/store';
import {
    
     todoReducer } from './todo.reducer';

@NgModule({
    
    
  imports: [
    // ...
    StoreModule.forRoot({
    
     todos: todoReducer }),
  ],
  declarations: [
    // ...
  ],
  bootstrap: [AppComponent],
})
export class AppModule {
    
    }

Step 6: Use Store in Component

Use Store in components to access and update state.

// todo.component.ts

import {
    
     Component } from '@angular/core';
import {
    
     Store } from '@ngrx/store';
import {
    
     addTodo, deleteTodo, toggleTodo } from './todo.actions';
import {
    
     AppState, Todo } from './app.state';

@Component({
    
    
  selector: 'app-todo',
  template: `
    <div>
      <input [(ngModel)]="newTodoText" placeholder="New Todo" />
      <button (click)="addTodo()">Add</button>
    </div>
    <ul>
      <li *ngFor="let todo of todos">
        <input type="checkbox" [(ngModel)]="todo.completed" (change)="toggleTodo(todo.id)" />
        {
    
    {
    
     todo.text }}
        <button (click)="deleteTodo(todo.id)">Delete</button>
      </li>
    </ul>
  `,
})
export class TodoComponent {
    
    
  newTodoText = '';
  todos: Todo[] = [];

  constructor(private store: Store<AppState>) {
    
    
    store.select((state) => state.todos).subscribe((todos) => (this.todos = todos));
  }

  addTodo() {
    
    
    if (this.newTodoText) {
    
    
      this.store.dispatch(addTodo({
    
     text: this.newTodoText }));
      this.newTodoText = '';
    }
  }

  deleteTodo(id: number) {
    
    
    this.store.dispatch(deleteTodo({
    
     id }));
  }

  toggleTodo(id: number) {
    
    
    this.store.dispatch(toggleTodo({
    
     id }));
  }
}

This is a simple example of how to use NgRx for state management. You can add more actions, reducers, and effects to handle more complex state management needs. Using NgRx can help you better organize and maintain the state of your Angular applications.

Guess you like

Origin blog.csdn.net/weixin_43160662/article/details/132725930