NgRx Introduction 🎯

beginner
21 min

NgRx Introduction 🎯

Welcome to the NgRx tutorial! In this comprehensive lesson, we'll explore Angular's state management solution - NgRx. By the end of this tutorial, you'll understand the "why" and "how" of NgRx, and be able to apply it to your own Angular projects. 📝

What is NgRx?

NgRx is a library for managing state in Angular applications. It is built on top of RxJS, providing a simple and powerful way to manage application state, handle asynchronous actions, and streamline data flow. 💡 Pro Tip: NgRx can make your Angular applications more scalable and maintainable.

Why Use NgRx?

NgRx is a great choice when you have complex state management needs, such as handling asynchronous actions, managing side effects, and sharing state between components. By using NgRx, you can:

  • Simplify state management
  • Improve the reusability of components
  • Make your application more testable
  • Facilitate collaboration among developers

NgRx Core Concepts

To use NgRx effectively, you'll need to understand the following core concepts:

Actions

Actions are the events that trigger changes to the application state. They are dispatched by components, services, or other parts of the application. 📝 Note: Actions are plain JavaScript objects that contain a type and, optionally, a payload.

Action Types

Action types are unique identifiers for each action. They are used to differentiate between different types of actions in your application. 💡 Pro Tip: Use a consistent naming convention for action types to make your code easier to understand.

Reducers

Reducers are pure functions that take the current state and an action as arguments and return the updated state. They define how the state is changed in response to an action. 📝 Note: Reducers should be immutable, meaning they should never modify the current state directly.

Selectors

Selectors are functions that allow you to select specific parts of the state. They are used to extract the data you need from the state and make it available to components or services. 💡 Pro Tip: Use selectors to improve the performance of your application by only retrieving the data you need when you need it.

Effects

Effects are functions that handle asynchronous actions, such as API calls or side effects. They are responsible for performing the necessary work, such as sending a request or updating the state, in response to an action. 📝 Note: Effects should be pure, meaning they should not modify the state directly. Instead, they should dispatch an action to update the state.

Example: Simple Todo App

Let's put our knowledge into practice by building a simple Todo app using NgRx. We'll create a list of todos that can be added, removed, and edited.

Action Types

First, let's define our action types:

typescript
export const ADD_TODO = '[Todo] Add Todo'; export const REMOVE_TODO = '[Todo] Remove Todo'; export const UPDATE_TODO = '[Todo] Update Todo';

Actions

Next, let's create our actions:

typescript
import { createAction, props } from '@ngrx/store'; export const addTodo = createAction(ADD_TODO, props<{ text: string }>()); export const removeTodo = createAction(REMOVE_TODO, props<{ index: number }>()); export const updateTodo = createAction(UPDATE_TODO, props<{ index: number; text: string }>());

Reducer

Now, let's create our reducer:

typescript
import { createReducer, on } from '@ngrx/store'; import { addTodo, removeTodo, updateTodo } from './todo.actions'; export interface State { todos: string[]; } export const initialState: State = { todos: [], }; const _todos = (state = initialState, action) => { switch (action.type) { case ADD_TODO: { const newTodos = [...state.todos, action.text]; return { ...state, todos: newTodos }; } case REMOVE_TODO: { const newTodos = [...state.todos.slice(0, action.index), ...state.todos.slice(action.index + 1)]; return { ...state, todos: newTodos }; } case UPDATE_TODO: { const updatedTodos = state.todos.map((todo, index) => (index === action.index ? action.text : todo)); return { ...state, todos: updatedTodos }; } default: { return state; } } }; export const todoReducer = createReducer(_todos);

Selectors

Finally, let's create a selector to retrieve the current list of todos:

typescript
import { createSelector } from '@ngrx/store'; export const selectTodos = (state: State) => state.todos; export const selectTodoAtIndex = createSelector( selectTodos, (todos, index) => todos[index] );

Wrapping Up

You've now completed the NgRx Introduction tutorial! You've learned the core concepts of NgRx, built a simple Todo app, and understood how NgRx can help you manage state in your Angular applications. ✅

Quiz

Quick Quiz
Question 1 of 1

What is the purpose of an action in NgRx?