Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NgRx Component Store
Search
Rainer Hahnekamp
July 20, 2022
Technology
1
120
NgRx Component Store
Slides for my talk on NgRx Component Store
Rainer Hahnekamp
July 20, 2022
Tweet
Share
More Decks by Rainer Hahnekamp
See All by Rainer Hahnekamp
Zurück in den Browser – Das Comeback der Frontend-Tests
rainerhahnekamp
0
17
From Hours to Minutes: An AI Case Study with Sheriff
rainerhahnekamp
0
24
RxJS, Signals & Native Observables
rainerhahnekamp
0
48
The Road to Angular Today Milestones, Mistakes & Momentum
rainerhahnekamp
0
55
Next Generation Angular
rainerhahnekamp
0
23
2025-09-05_Hold_the_Line.pdf
rainerhahnekamp
0
160
Test Fest | Angular Unit Tests Distilled
rainerhahnekamp
0
440
Micro Frontends: Necessity, Implementation, and Challenges
rainerhahnekamp
2
940
Software richtig testen - Ganz praktisch!
rainerhahnekamp
0
140
Other Decks in Technology
See All in Technology
AI駆動開発2025年振り返りとTips集
knr109
1
130
Digital omtanke på Internetdagarna 2025
axbom
PRO
0
130
AI エージェントを評価するための温故知新と Spec Driven Evaluation
icoxfog417
PRO
2
890
AI エージェント活用のベストプラクティスと今後の課題
asei
2
380
Pandocでmd→pptx便利すぎワロタwww
meow_noisy
2
990
メッセージ駆動が可能にする結合の最適化
j5ik2o
9
1.6k
AS59105におけるFreeBSD EtherIPの運用と課題
x86taka
0
280
自然言語でAPI作業を片付ける!「Postman Agent Mode」
nagix
0
150
mablでリグレッションテストをデイリー実行するまで #mablExperience
bengo4com
0
410
プロダクト負債と歩む持続可能なサービスを育てるための挑戦
sansantech
PRO
1
1.1k
GitHub を組織的に使いこなすために ソニーが実践した全社展開のプラクティス
sony
6
3.3k
クラスタ統合リアーキテクチャ全貌~1,000万ユーザーのウェルネスSaaSを再設計~
hacomono
PRO
0
200
Featured
See All Featured
Code Review Best Practice
trishagee
72
19k
Into the Great Unknown - MozCon
thekraken
40
2.2k
Bash Introduction
62gerente
615
210k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
980
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Building Adaptive Systems
keathley
44
2.8k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.8k
Designing for Performance
lara
610
69k
BBQ
matthewcrist
89
9.9k
Site-Speed That Sticks
csswizardry
13
970
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
36
6.1k
Transcript
NgRx Component Store NgRx Component Store Rainer Hahnekamp 20.7.2022
About Me... • Rainer Hahnekamp ANGULARarchitects.io • Trainings and Consulting
@RainerHahnekamp Professional NgRx https://www.ng-news.com https://www.youtube.com /c/RainerHahnekamp
Agenda • NgRx Family • Theory • Selectors • Actions
• Effects • Miscellaneous
NgRx Family Store Effects Entity Data Router Store Store Devtools
Schematics ESLint Plugin Component Store Component
Main facts • (Little) sibling to @ngrx/store • Local /
component state management • State vanishes with component (by default) • Push-based • All logic included in single service
Use cases • Complicated, local state logic • Multiple instances
of same components • Different static logic (Decoupling, Shared) • ~Simplified, global state
API ComponentStore SideEffects Read Write select(): Observable patchState() setState() updater()
// like reducer effect()
Defining the state export interface HolidaysState { holidays: Holiday[]; favouriteIds:
number[]; } @Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { constructor(private httpClient: HttpClient, private config: Configuration) { super({ holidays: [], favouriteIds: [] }); } }
Selectors export interface HolidaysState { holidays: Holiday[]; favouriteIds: number[]; }
@Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { constructor(private httpClient: HttpClient, private config: Configuration) { super({ holidays: [], favouriteIds: [] }); } readonly holidays$ = this.select(({ holidays, favouriteIds }) => holidays.map((holiday) => ({ ...holiday, isFavourite: favouriteIds.includes(holiday.id), })) ); }
Using the ComponentStore @Component({ templateUrl: './holidays.component.html', standalone: true, imports: [...],
providers: [HolidaysStore], }) export class HolidaysComponent { holidays$ = this.holidaysStore.holidays$; constructor(private holidaysStore: HolidaysStore) { } }
Actions @Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { // ...
addFavourite(holidayId: number) { this.patchState((state) => ({ favouriteIds: [...state.favouriteIds, holidayId], })); } removeFavourite(holidayId: number) { this.patchState((state) => ({ favouriteIds: state.favouriteIds.filter((id) => id !== holidayId), })); } }
Using the ComponentStore @Component({ templateUrl: './holidays.component.html', standalone: true, imports: [...],
providers: [HolidaysStore], }) export class HolidaysComponent { holidays$ = this.holidaysStore.holidays$; constructor(private holidaysStore: HolidaysStore) { } addFavourite(id: number) { this.holidaysStore.addFavourite(id); } removeFavourite(id: number) { this.holidaysStore.removeFavourite(id); } }
Effects @Injectable() export class HolidaysStore extends ComponentStore<HolidaysState> { // ...
readonly load = this.effect((i$: Observable<void>) => { return i$.pipe( switchMap(() => this.httpClient.get<Holiday[]>(this.#baseUrl).pipe( tapResponse((holidays) => { const finalHolidays = holidays.map((holiday) => ({ ...holiday, imageUrl: `${this.config.baseUrl}${holiday.imageUrl}`, })); this.#setHolidays(finalHolidays); }, console.error) ) ) ); }); #setHolidays = (holidays: Holiday[]) => this.patchState({ holidays }); }
Using the ComponentStore @Component({ templateUrl: './holidays.component.html', standalone: true, imports: [...],
providers: [HolidaysStore], }) export class HolidaysComponent { holidays$ = this.holidaysStore.holidays$; constructor(private holidaysStore: HolidaysStore) { this.holidaysStore.load(); } addFavourite(id: number) { this.holidaysStore.addFavourite(id); } removeFavourite(id: number) { this.holidaysStore.removeFavourite(id); } }
Comparison to store • Same reactive behaviour • No devtools
• Scalability issues • Simpler • Nice goodies ◦ patchState ◦ Debounced selectors
Also keep in mind • Disposing of resources is built-in
• Combination with @ngrx/store possible • Can also manage global state ◦ via {providedIn: 'root'}
When to use? • Instead of services based on BehaviorSubject
• Non-global state • Early phases of application development
Alternatives Elf @rx-angular/state
Summary • Simple State Management • Reactive Behaviour • Easy
to upgrade to NgRx Store later
Further Reading/Watching • Original Design Document ◦ https://hackmd.io/zLKrFIadTMS2T6zCYGyHew?view • Official
Documentation ◦ https://ngrx.io/guide/component-store • Alex Okrushko on Component Store ◦ https://www.youtube.com/watch?v=v5WSUE1_YHM