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
From Hours to Minutes - An AI Case Study with Sheriff
rainerhahnekamp
0
9
RxJS, Signals, and Native Observables: Answering the Critical Questions
rainerhahnekamp
0
9
Zurück in den Browser – Das Comeback der Frontend-Tests
rainerhahnekamp
0
40
From Hours to Minutes: An AI Case Study with Sheriff
rainerhahnekamp
0
56
RxJS, Signals & Native Observables
rainerhahnekamp
0
73
The Road to Angular Today Milestones, Mistakes & Momentum
rainerhahnekamp
0
79
Next Generation Angular
rainerhahnekamp
0
35
2025-09-05_Hold_the_Line.pdf
rainerhahnekamp
0
190
Test Fest | Angular Unit Tests Distilled
rainerhahnekamp
0
450
Other Decks in Technology
See All in Technology
まだ間に合う! Agentic AI on AWSの現在地をやさしく一挙おさらい
minorun365
19
3.1k
コールドスタンバイ構成でCDは可能か
hiramax
0
120
2025年のデザインシステムとAI 活用を振り返る
leveragestech
0
430
Autonomous Database - Dedicated 技術詳細 / adb-d_technical_detail_jp
oracle4engineer
PRO
5
11k
AIエージェントを5分で一気におさらい!AIエージェント「構築」元年に備えよう
yakumo
1
120
Bedrock AgentCore Evaluationsで学ぶLLM as a judge入門
shichijoyuhi
2
290
20251222_サンフランシスコサバイバル術
ponponmikankan
2
150
TED_modeki_共創ラボ_20251203.pdf
iotcomjpadmin
0
170
Microsoft Agent Frameworkの可観測性
tomokusaba
1
120
『君の名は』と聞く君の名は。 / Your name, you who asks for mine.
nttcom
1
130
Keynoteから見るAWSの頭の中
nrinetcom
PRO
1
110
[Data & AI Summit '25 Fall] AIでデータ活用を進化させる!Google Cloudで作るデータ活用の未来
kirimaru
0
4.1k
Featured
See All Featured
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
140
Building a Scalable Design System with Sketch
lauravandoore
463
34k
The Invisible Side of Design
smashingmag
302
51k
How to make the Groovebox
asonas
2
1.9k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
270
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Un-Boring Meetings
codingconduct
0
170
The World Runs on Bad Software
bkeepers
PRO
72
12k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
The Limits of Empathy - UXLibs8
cassininazir
1
190
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