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
8
Towards Modern Change Detection
rainerhahnekamp
0
270
Cypress or Playwright?
rainerhahnekamp
0
200
Powerduo Nx and Sheriff
rainerhahnekamp
0
68
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
Exadata Database Service on Dedicated Infrastructure(ExaDB-D) UI スクリーン・キャプチャ集
oracle4engineer
PRO
2
1.7k
OpenID Foundation updates
fujie
0
240
データ分析力を高めるSQL研修サービス『SQL Everyone』
hikarut
1
400
B2C、B2B プロダクトマネジメントの違い(および思考の罠) / B2C, B2B PM and reduction fallacy
ykmc09
5
2.5k
知識と実践を紡ぐGenAI / Connecting Knowledge and experience with GenAI
aki_moon
2
190
動画配信サービスのフロントエンド実装に学ぶ設計原則
yud0uhu
1
140
Oracle Cloud Infrastructureデータベース・クラウド:各バージョンのサポート期間
oracle4engineer
PRO
12
7.9k
生成AIと産業向けソフトウェアの自動生成 〜 ハノーバーメッセ2024より〜
kioto
2
440
20240509 CloudWatch でいろいろなものを監視してみよう
masaruogura
1
120
AI JIMY - 登壇(インストール編)
hanacchi
0
150
Google Cloudを組織(企業)で運用する時のベストプラクティス × 健康の環境分離戦略 #まるクラ勉強会
yasumuusan
0
190
能動学習のいろは:書籍「Human-in-the-Loop機械学習」3〜5章
hiroyoshiito
0
310
Featured
See All Featured
Intergalactic Javascript Robots from Outer Space
tanoku
266
26k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Visualization
eitanlees
137
14k
Principles of Awesome APIs and How to Build Them.
keavy
121
16k
Large-scale JavaScript Application Architecture
addyosmani
504
110k
Making the Leap to Tech Lead
cromwellryan
125
8.6k
Into the Great Unknown - MozCon
thekraken
15
1.1k
Robots, Beer and Maslow
schacon
PRO
155
8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
649
58k
Testing 201, or: Great Expectations
jmmastey
30
6.4k
Imperfection Machines: The Place of Print at Facebook
scottboms
261
12k
WebSockets: Embracing the real-time Web
robhawkes
59
7k
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