If you enjoy clever analogies to make coding concepts click, give this a like or share it with a friend who’s wrestling with NgRx selectors!
I think of NgRx selectors like I think about a tailored wardrobe in a giant walk-in closet. Picture this: I’ve got this enormous closet, and it’s stuffed with every single piece of clothing I own—jackets, shirts, shoes, hats, you name it. That’s my NgRx store, holding all my state.
Now, when I want to get dressed, I could dig through the whole closet to find my favorite shirt and pair of sneakers. But that takes forever, and let’s be honest, I’d end up making a mess every time. Instead, I’ve set up little drawers and sections in my closet. One drawer is labeled “Workout Gear,” and when I open it, boom—everything I need for the gym is right there. Another section is “Party Outfits,” perfectly organized for when I’m in the mood to celebrate.
That’s what selectors do in NgRx. They’re like those pre-organized drawers and sections. Instead of rummaging through the entire state every time I need something, a selector pulls just the exact pieces I want: the user profile, the shopping cart total, or the list of todos.
And the magic? Because I’m only ever looking at what I need, everything feels faster. My closet (the NgRx store) doesn’t get overwhelmed, and I don’t waste time hunting. It’s efficient, clean, and keeps my sanity intact.
So next time someone mentions NgRx selectors, just think of your perfect closet setup. It’s all about finding what you need without tearing apart the whole store—and that’s how selectors keep performance sharp and organized.
In JavaScript, NgRx selectors let us efficiently pick out specific parts of the store’s state, just like those well-organized wardrobe drawers. Here’s what that looks like in code:
Setting Up the Store
Imagine we have an NgRx store holding all our state:
export interface AppState {
user: { name: string; age: number; loggedIn: boolean };
cart: { items: { id: number; name: string; quantity: number }[]; total: number };
}
This is our gigantic closet stuffed with every possible item.
Creating a Selector (The Organized Drawer)
Now let’s say I only want the user’s name from the user
slice of the store. Instead of digging through the entire state every time, I can use a selector:
import { createSelector } from '@ngrx/store';
export const selectUser = (state: AppState) => state.user;
export const selectUserName = createSelector(
selectUser,
(user) => user.name
);
Here’s what’s happening:
selectUser
is like opening the “user” section of the closet.selectUserName
zooms in on the exact item I want: the user’s name.
Using the Selector (Pulling Items Quickly)
Now, in a component, I can use the selector with NgRx’s Store
service:
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { selectUserName } from './selectors';
@Component({
selector: 'app-profile',
template: `<h1>Hello, {{ userName$ | async }}</h1>`
})
export class ProfileComponent {
userName$: Observable<string>;
constructor(private store: Store<AppState>) {
this.userName$ = this.store.select(selectUserName);
}
}
Instead of subscribing to the whole state and filtering out the name myself, I get just the user’s name—efficient and clean.
More Complex Drawers
Let’s say I want to calculate the total number of items in the cart. I can create another selector:
export const selectCart = (state: AppState) => state.cart;
export const selectTotalItems = createSelector(
selectCart,
(cart) => cart.items.reduce((total, item) => total + item.quantity, 0)
);
This is like having a drawer labeled “Total Items,” so I don’t need to calculate it from scratch every time.
Key Takeaways
- Selectors Reduce Complexity: They keep your components clean by abstracting the logic for accessing state.
- Improved Performance: Selectors are memoized by default, meaning they remember the last result unless the state changes, reducing unnecessary recalculations.
- Maintainable Code: Instead of repeating logic in multiple components, selectors centralize it in one place, making your code easier to update and debug.
Leave a Reply