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
Testing Angular in 2024
rainerhahnekamp
0
6
Towards Modern Change Detection
rainerhahnekamp
0
270
Cypress or Playwright?
rainerhahnekamp
0
200
Powerduo Nx and Sheriff
rainerhahnekamp
0
67
NgRx Signal Store
rainerhahnekamp
0
200
Signals Unleashed: The Full Guide
rainerhahnekamp
0
470
Change Detection - Deep Dive
rainerhahnekamp
0
170
NgRx Signal Store
rainerhahnekamp
0
84
Basta Spring 2024 - Cypress und Playwright
rainerhahnekamp
0
300
Other Decks in Technology
See All in Technology
「知的単純作業」を自動化する、地に足の着いた大規模言語モデル (LLM) の活用
nrryuya
8
8.3k
20240509 CloudWatch でいろいろなものを監視してみよう
masaruogura
1
120
「できる!」を増やすGitHub Copilot活用法 / How to use GitHub Copilot to expand your possibilities
sansan_randd
1
240
From here to resilience - a travel guide
ufried
1
160
個人的、Kubernetes の最新注目機能! (2024年5月版) / TechFeed Experts Night#28 〜 コンテナ技術最前線
pfn
PRO
3
210
Password cracking: past, present, future
openwall
0
280
[2024년 5월 세미나] 생성형 AI와 함께하는 데이터 분석가 커리어
datarian
0
1.2k
技術力の伸ばし方を考える
khirata
0
140
Google Cloudを組織(企業)で運用する時のベストプラクティス × 健康の環境分離戦略 #まるクラ勉強会
yasumuusan
0
170
My road to OSEE Part1
yunolay
0
120
The depthes of profiling Ruby - RubyKaigi 2024
osyoyu
0
170
サービス開発におけるVue3とTypeScriptの親和性について
tsukuha
10
1.8k
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
62
5k
5 minutes of I Can Smell Your CMS
philhawksworth
199
19k
Designing with Data
zakiwarfel
96
4.8k
Code Reviewing Like a Champion
maltzj
516
39k
StorybookのUI Testing Handbookを読んだ
zakiyama
13
4.7k
From Idea to $5000 a Month in 5 Months
shpigford
377
45k
Embracing the Ebb and Flow
colly
80
4.2k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
34
6.1k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
15
1.6k
Typedesign – Prime Four
hannesfritz
36
2.1k
How to Ace a Technical Interview
jacobian
273
22k
How STYLIGHT went responsive
nonsquared
92
4.9k
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