1. Understand Memoized Selector
exist@ngrx/store
In the development package,MemoizedSelector
is an important concept and tool for managing and selecting fragments of Redux state in Angular applications. It is@ngrx/store
A key feature of by usingreselect
Library to optimize state selectors.MemoizedSelector
The performance of the state selector can be improved and unnecessary state calculations can be avoided, thereby improving the efficiency and responsiveness of the application.
In this article, we will gain a deeper understanding ofMemoizedSelector
The concept and usage of , and use specific examples to illustrate its usage and advantages.
State management is very important in Redux applications. use@ngrx/store
The development package can easily implement the Redux mode in Angular applications. Where, the selector is a function used to obtain a specific data fragment from the Redux state tree. The selector allows us to organize and reuse state read logic in our application.
@ngrx/store
The selectors in are divided into two categories:
- Normal selector: A new result is calculated and returned every time it is called. This can cause performance issues, especially when computed in complex states.
- Memoized selector (MemoizedSelector): Use
reselect
A selector implemented by the library. The Memoized selector caches the calculated results and returns the cached results directly under the same input conditions without recalculating. This avoids unnecessary computing and performance losses.
2. Usage of Memoized Selector
In Angular applications, we usually usecreateFeatureSelector
andcreateSelector
Functions to define Memoized selectors.createFeatureSelector
Used to create selectors under a specific feature, andcreateSelector
Used to create specific Memoized selectors.
2.1 Create Feature Selector (createFeatureSelector)
createFeatureSelector
The function is used to create a selector under a specific feature, which takes the identifier of a specific feature as a parameter and returns a selector function. This selector function selects a state fragment under a specific feature from the root state.
import { createFeatureSelector } from '@ngrx/store'; // Create Feature selectorconst featureSelector = createFeatureSelector<FeatureState>('featureName');
In the above code, we created a name calledfeatureSelector
Feature selector and identifies it with the identifier of the specific feature'featureName'
Related. so,featureSelector
Will be used to select from the name'featureName'
The status clip under the feature.
2.2 Create a Memoized selector (createSelector)
createSelector
Functions are used to create a Memoized selector, which receives a series of input selectors (can be Feature selectors or other Memoized selectors), and an output function. The output function is used to select a specific state fragment from the result of the input selector and perform arbitrary conversion or calculation.
import { createSelector } from '@ngrx/store'; // Create Memoized selectorconst memoizedSelector = createSelector( featureSelector, (featureState) => );
In the above code, we created a name calledmemoizedSelector
Memoized selector. It receives fromfeatureSelector
The resultfeatureState
As input, then select fromThis status clip. Here
someData
It can be a certain attribute under a specific feature or a state obtained through complex calculations.
The Memoized selector will be cachedThe calculation result of and directly return the cached result under the same input conditions to avoid unnecessary calculations.
2.3 Using the Memoized Selector
The process of using the Memoized selector in an application is very simple. We can call the Memoized selector just like we call a normal function and pass in the required input conditions. The Memoized selector will make status selections based on the input conditions and return cached results or return results after calculation.
// Use Memoized selector(memoizedSelector).subscribe((data) => { ('Selected data:', data); });
In the above code, we pass()
Method callmemoizedSelector
Memoized selector and passsubscribe
Changes in subscription status. When the state changes,memoizedSelector
The status selection will be made according to the input conditions and the cached result or calculated result will be returned. Finally, we will see the output of the selected data in the console.
3. Advantages of Memoized Selector
The Memoized selector has many advantages in Angular applications, especially when dealing with complex state calculations:
3.1 Improve performance
The Memoized selector caches the results of the calculation to avoid unnecessary state calculations, thereby improving application performance. When the input conditions of the selector have not changed, the Memoized selector will return the previously cached result directly without recalculating. This is particularly important in large applications and complex state computing, which can reduce the overhead of repeated calculations and improve the response performance of the application.
3.2 Avoid unnecessary status updates
Since the Memoized selector caches the calculated results, when the state changes, the Memoized selector returns a new result only when the data dependent on the input conditions changes. This can avoid unnecessary state updates, reduce unnecessary component re-rendering, and improve application efficiency.
3.3 Support complex state calculation
The Memoized selector is ideal for handling complex state computing logic. By combining multiple selectors and output functions, we can easily implement complex state transitions and calculations. Memoized selector
The caching mechanism ensures that state calculations are performed only when necessary, avoiding duplicate work.
3.4 Code reuse and organization
The Memoized selector allows us to separate state selection logic from components to implement code reuse and organization. We can place complex state selection logic in Memoized selectors and reuse them in different components. This keeps the components simple and easier to maintain.
4. Example: Use the Memoized selector to manage cart status
Now, we demonstrate how to use the Memoized selector to manage complex state logic with a shopping cart example. Suppose we have a shopping cart app that contains multiple items and cart status. Each item has a unique ID, name, price, and quantity. Cart Status is a collection of all items in the cart.
We first define the status interface of the shopping cart:
interface CartItem { id: number; name: string; price: number; quantity: number; } interface CartState { items: CartItem[]; total: number; }
Next, we create the shopping cart@ngrx/store
Feature module and define a Memoized selector to manage shopping cart status.
// import { createAction, props } from '@ngrx/store'; import { CartItem } from './'; // Add items to cartexport const addToCart = createAction( '[Cart] Add To Cart', props<{ item: CartItem }>() ); // Remove items from cartexport const removeFromCart = createAction( '[Cart] Remove From Cart', props<{ itemId: number }>() ); // import { createReducer, on } from '@ngrx/store'; import { CartState, CartItem } from './'; import { addToCart, removeFromCart } from './'; // Initialize the shopping cart statusconst initialState: CartState = { items: [], total: 0, }; // Create a shopping cart status reducerexport const cartReducer = createReducer( initialState, on(addToCart, (state, { item }) => { // Determine whether the product already exists in the shopping cart const existingItem = ((i) => === ); if (existingItem) { // The product already exists, updated quantity and total price const updatedItems = ((i) => === ? { ...i, quantity: + 1 } : i ); return { ...state, items: updatedItems, total: + , }; } else { // The product does not exist, add new product to the cart const newItem: CartItem = { ...item, quantity: 1 }; return { ...state, items: [..., newItem], total: + , }; } }), on(removeFromCart, (state, { itemId }) => { // Delete items from cart by item ID const updatedItems = ((i) => !== itemId); const removedItem = ((i) => === itemId); return { ...state, items: updatedItems, total: - (removedItem ? * : 0), }; }) );
In the above code, we first define the shopping cart status interface.CartState
Interface with productsCartItem
. Next, we created two@ngrx/store
The action:addToCart
andremoveFromCart
. These actions will be used to modify the status of the shopping cart.
Then we define the status of the shopping cart reducercartReducer
, whereon
Functions to handle different actions. existaddToCart
In the processing logic, we judge whether the product already exists in the shopping cart, if it exists, the quantity and total price will be updated, otherwise new products will be added to the shopping cart. existremoveFromCart
In the processing logic, we delete the item from the shopping cart based on the product ID and update the total price accordingly.
Now, let's create a Memoized selector to select a specific data segment from the cart state.
// import { createFeatureSelector, createSelector } from '@ngrx/store'; import { CartState } from './'; // Create a shopping cart Feature selectorexport const selectCartState = createFeatureSelector<CartState>('cart'); // Create Memoized selector: select all items in the shopping cartexport const selectCartItems = createSelector( selectCartState, (cartState) => ); // Create Memoized selector: select the total price of items in the shopping cartexport const selectCartTotal = createSelector( selectCartState, (cartState) => );
In the above code, we first usecreateFeatureSelector
Feature selector for creating shopping cartselectCartState
. Next, we usecreateSelector
To create two Memoized selectors:selectCartItems
andselectCartTotal
。selectCartItems
Memoized selector selects the cart statusitems
,andselectCartTotal
Select the shopping cart statustotal
。
Now we can use these Memoized selectors in our components to select specific data snippets of the cart state.
// import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { CartItem } from './'; import { addToCart, removeFromCart } from './'; import { selectCartItems, selectCartTotal } from './'; import { Observable } from 'rxjs'; @Component({ selector: 'app-cart', template: ` <h2>Shopping Cart</h2> <div *ngFor="let item of cartItems$ | async"> <p>{{ }} - Quantity: {{ }} - Price: ${{ }}</p> <button (click)="removeItemFromCart()">Remove</button> </div> <p>Total Price: ${{ cartTotal$ | async }}</p> `, }) export class CartComponent { cartItems$: Observable<CartItem[]>; cartTotal$: Observable<number>; constructor(private store: Store) { $ = (selectCartItems); $ = (selectCartTotal); } addItemToCart(item: CartItem) { (addToCart({ item })); } removeItemFromCart(itemId: number) { (removeFromCart({ itemId })); } }
In the shopping cart component, we use()
Method callselectCartItems
andselectCartTotal
Memoized selector to get all items and total prices in the cart. Then, we useasync
Pipelines to process Observable data, displaying the shopping cart's product list and total price in real time.
By using the Memoized selector, we can efficiently manage shopping cart status and update the application interface dynamically based on items in the cart.
5. Summary
MemoizedSelector
yes@ngrx/store
An important concept in the development package, it is used byreselect
Library to optimize state selectors. Memoized selectors can improve application performance, avoid unnecessary state calculations, and support the processing of complex state logic.
passcreateFeatureSelector
andcreateSelector
Functions, we can easily create selectors and Memoized selectors under specific features. Memoized selectors are very useful in Angular applications, especially when managing large state trees and complex state computing, which can effectively improve application performance and responsiveness.
In actual development, we should make full use ofMemoizedSelector
, and abstract the state selection logic into a reusable selector as much as possible to improve the maintainability and reusability of the code. At the same time, we should also be careful to avoid abuse of Memoized selectors and avoid creating too many selectors that lead to unnecessary memory usage. Taking into account performance and maintainability into account, the rational use of Memoized selectors will help build efficient and scalable Angular applications.
The above is the detailed content of what is the MemoizedSelector in the @ngrx/store development package. For more information about the MemoizedSelector in the @ngrx/store development package, please follow my other related articles!