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
72
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
Towards Modern Change Detection
rainerhahnekamp
0
270
Cypress or Playwright?
rainerhahnekamp
0
200
Powerduo Nx and Sheriff
rainerhahnekamp
0
66
NgRx Signal Store
rainerhahnekamp
0
190
Signals Unleashed: The Full Guide
rainerhahnekamp
0
470
Change Detection - Deep Dive
rainerhahnekamp
0
170
NgRx Signal Store
rainerhahnekamp
0
83
Basta Spring 2024 - Cypress und Playwright
rainerhahnekamp
0
300
Powerduo Nx and Sheriff
rainerhahnekamp
0
80
Other Decks in Technology
See All in Technology
株式会社EventHub・エンジニア採用資料
eventhub
0
2.1k
Dungeons and Dragons and Rails
joelq
0
220
使われないものを作るな!出口から作るデータ分析基盤 / Data Platform Development Starting from the User Needs
amaotone
16
4.3k
本番環境で Cloudflareを 使ってみた話
miu_crescent
2
120
cgroup v2 で何が変わったのか / TechFeed Experts Night #28
tenforward
2
150
AWS Observability ベストプラクティス 大紹介
o11yfes2023
0
150
TDD - Test Driven Drupal
opdavies
0
3k
試作とデモンストレーション / Prototyping and Demonstrations
ks91
PRO
0
160
動画配信サービスのフロントエンド実装に学ぶ設計原則
yud0uhu
0
130
B2C、B2B プロダクトマネジメントの違い(および思考の罠) / B2C, B2B PM and reduction fallacy
ykmc09
5
2.1k
From here to resilience - a travel guide
ufried
1
160
Google Cloudを組織(企業)で運用する時のベストプラクティス × 健康の環境分離戦略 #まるクラ勉強会
yasumuusan
0
160
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
20
1.8k
How To Stay Up To Date on Web Technology
chriscoyier
782
250k
The Straight Up "How To Draw Better" Workshop
denniskardys
228
130k
Bash Introduction
62gerente
605
210k
Product Roadmaps are Hard
iamctodd
45
9.8k
Stop Working from a Prison Cell
hatefulcrawdad
266
19k
A designer walks into a library…
pauljervisheath
201
23k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
104
6.7k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
15
1.6k
A better future with KSS
kneath
231
16k
Visualization
eitanlees
137
14k
Facilitating Awesome Meetings
lara
43
5.6k
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