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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Rainer Hahnekamp
July 20, 2022
Technology
1
130
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
Vitest Highlights in Angular
rainerhahnekamp
0
210
From Hours to Minutes - An AI Case Study with Sheriff
rainerhahnekamp
0
22
RxJS, Signals, and Native Observables: Answering the Critical Questions
rainerhahnekamp
0
23
Zurück in den Browser – Das Comeback der Frontend-Tests
rainerhahnekamp
0
62
From Hours to Minutes: An AI Case Study with Sheriff
rainerhahnekamp
0
110
RxJS, Signals & Native Observables
rainerhahnekamp
0
120
The Road to Angular Today Milestones, Mistakes & Momentum
rainerhahnekamp
0
110
Next Generation Angular
rainerhahnekamp
0
48
2025-09-05_Hold_the_Line.pdf
rainerhahnekamp
0
220
Other Decks in Technology
See All in Technology
生成AI活用によるPRレビュー改善の歩み
lycorptech_jp
PRO
5
2k
LLM活用の壁を超える:リクルートR&Dの戦略と打ち手
recruitengineers
PRO
1
220
クラウド時代における一時権限取得
krrrr38
1
150
Digitization部 紹介資料
sansan33
PRO
1
7k
男(監査)はつらいよ - Policy as CodeからAIエージェントへ
ken5scal
5
720
OpenClawで回す組織運営
jacopen
1
110
Oracle Cloud Infrastructure:2026年2月度サービス・アップデート
oracle4engineer
PRO
0
210
技術的負債の泥沼から組織を救う3つの転換点
nwiizo
5
1.3k
どこで打鍵するのが良い? IaCの実行基盤選定について
nrinetcom
PRO
2
160
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
6
72k
Serverless Agent Architecture on Azure / serverless-agent-on-azure
miyake
1
130
Ultra Ethernet (UEC) v1.0 仕様概説
markunet
3
140
Featured
See All Featured
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
120
Automating Front-end Workflow
addyosmani
1370
200k
Building the Perfect Custom Keyboard
takai
2
710
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Designing for Performance
lara
611
70k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
63
The Invisible Side of Design
smashingmag
302
51k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
170
Side Projects
sachag
455
43k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
260
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