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
150
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
NgRx Component Store
Slides for my talk on NgRx Component Store
Rainer Hahnekamp
July 20, 2022
More Decks by Rainer Hahnekamp
See All by Rainer Hahnekamp
Angular Architecture Revisited Modernizing Angular Architectural Patterns
rainerhahnekamp
0
250
NgRx SignalStore: The Power of Extensibility
rainerhahnekamp
0
380
Vitest Highlights in Angular
rainerhahnekamp
0
430
From Hours to Minutes - An AI Case Study with Sheriff
rainerhahnekamp
0
59
RxJS, Signals, and Native Observables: Answering the Critical Questions
rainerhahnekamp
0
51
Zurück in den Browser – Das Comeback der Frontend-Tests
rainerhahnekamp
0
130
From Hours to Minutes: An AI Case Study with Sheriff
rainerhahnekamp
0
240
RxJS, Signals & Native Observables
rainerhahnekamp
0
210
The Road to Angular Today Milestones, Mistakes & Momentum
rainerhahnekamp
0
200
Other Decks in Technology
See All in Technology
FPGAが実現する遠方宇宙の高空間分解能天体撮影 -大型地上望遠鏡の視力を補正する「補償光学」とは?-
komei_mt
0
180
Cursor Meetup Sapporo - Cursor物語 続編
cocacola917
0
140
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
4.9k
【CEDEC2026】『ウマ娘 プリティーダービー』 英語版のキャラクターの方言や口調をローカライズするための創造的アプローチ
cygames
PRO
1
200
取引先から届く 「セキュリティチェックシート」の読み解き方
kamadamakoto
0
130
ブラウザ研修 2026
recruitengineers
PRO
4
780
修正PRを食べてレビュースキルが賢くなる:Claude Codeによる自己改善サイクル
yuyaumetsu
5
1.4k
Breaking the Seal: Static Deobfuscation of Compiled V8 JavaScript Bytecode Malware
hshrzd
0
650
SO-101×VLAによる3色キューブのピック&プレース
abeja
0
140
AI ネイティブな組織に Gemini Enterprise Agent Platform がなぜ必要なのか
asei
1
190
関東Kaggler会発表資料
takoi
1
180
今こそ聞きたいソフトウェア設計 ドメイン駆動設計再入門
masuda220
PRO
17
6.7k
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
119
120k
[SF Ruby Conf 2025] Rails X
palkan
2
1.2k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.7k
The Curse of the Amulet
leimatthew05
2
14k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
160
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
380
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Visualization
eitanlees
152
17k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
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