Angular NgRx Store
Learn Angular NgRx Store with architecture diagrams, Store configuration, feature stores, selectors, Signals integration, enterprise best practices, and interview questions.
The NgRx Store is the heart of NgRx State Management.
It provides a single source of truth for your application's state.
Instead of every component maintaining its own shared data, the Store centrally manages state, making applications:
- Predictable
- Scalable
- Easier to debug
- Easier to test
- Easier to maintain
In enterprise Angular applications, the Store acts as the central data hub that every feature can access.
Table of Contents
- What is NgRx Store?
- Why Use Store?
- Store Architecture
- Creating the Store
- Feature Stores
- Reading State
- Updating State
- Store + Signals
- Enterprise Banking Example
- Performance Best Practices
- Common Mistakes
- Top 10 Interview Questions
- Summary
What is NgRx Store?
The Store is a centralized container that holds the application's state.
Instead of components modifying data directly,
components:
- Dispatch Actions
- Read data from Selectors
- React to state changes
The Store itself is read-only.
Only Reducers can update its state.
Store Architecture
flowchart LR
Component
Component --> DispatchAction
DispatchAction --> Reducer
Reducer --> Store
Store --> Selector
Selector --> Component
Why Use NgRx Store?
Without Store
- Duplicate state
- Component communication becomes difficult
- Hard debugging
- Inconsistent updates
With Store
- Single source of truth
- Predictable state updates
- Better separation of concerns
- Easier debugging
- Better scalability
Store Data Flow
flowchart TD
User
User --> Component
Component --> Action
Action --> Reducer
Reducer --> Store
Store --> Selector
Selector --> UI
Creating the Store
Application State
export interface AppState {
customers: Customer[];
loading: boolean;
}
Register Store
bootstrapApplication(AppComponent, {
providers: [
provideStore({
customer: customerReducer
})
]
});
The Store now manages the customer feature state.
Root Store Architecture
flowchart LR
CustomerReducer --> RootStore
OrderReducer --> RootStore
AuthReducer --> RootStore
RootStore --> Application
Feature Stores
Large applications divide state into features.
Example
Store
├── Auth
├── Customers
├── Orders
├── Products
├── Payments
├── Notifications
└── Settings
Each feature owns its own state.
Feature Store Registration
provideState(
customerFeature
);
Feature Stores improve:
- Scalability
- Modularity
- Lazy loading
- Maintainability
Reading Data from Store
Components never access Store state directly.
Instead,
they use Selectors.
customers$ =
this.store.select(
selectCustomers
);
Template
<ul>
<li
*ngFor="let customer of customers$ | async">
{{ customer.name }}
</li>
</ul>
Store Read Flow
flowchart LR
Store
Store --> Selector
Selector --> Observable
Observable --> Component
Component --> UI
Updating Store
Components dispatch Actions.
this.store.dispatch(
loadCustomers()
);
Reducers update Store state.
Components never call reducers directly.
Update Flow
flowchart TD
Button
Button --> Dispatch
Dispatch --> Reducer
Reducer --> Store
Store --> UI
Store Immutability
State should never be mutated.
❌ Wrong
state.customers.push(customer);
✅ Correct
return {
...state,
customers: [
...state.customers,
customer
]
};
Immutability enables:
- Predictable updates
- Easier debugging
- Time-travel debugging
- Better change detection
Store with Signals
Modern Angular allows Selectors to become Signals.
customers =
toSignal(
this.store.select(
selectCustomers
)
);
Template
@for(
customer of customers();
track customer.id
){
{{ customer.name }}
}
Benefits
- Cleaner templates
- Automatic reactivity
- Better developer experience
Signals + Store
flowchart LR
Store
Store --> Selector
Selector --> Signal
Signal --> Component
Component --> UI
Store Snapshot
Sometimes you need a one-time value.
Example
this.store
.select(selectCustomer)
.pipe(take(1))
.subscribe(customer => {
console.log(customer);
});
For continuous UI updates,
prefer Selectors or Signals over one-time reads.
Enterprise Banking Example
Banking Dashboard
Store Structure
Store
├── Authentication
├── Customer
├── Accounts
├── Transactions
├── Cards
├── Loans
├── Investments
├── Notifications
└── Preferences
Architecture
flowchart TD
Dashboard
Dashboard --> Store
Store --> Selectors
Selectors --> Signals
Signals --> Dashboard
Dashboard --> User
Benefits
- Centralized state
- Consistent data
- Easy debugging
- Feature isolation
- Better scalability
Store Folder Structure
store/
├── auth/
│ ├── auth.actions.ts
│ ├── auth.reducer.ts
│ ├── auth.selectors.ts
│ ├── auth.effects.ts
│
├── customers/
│ ├── customer.actions.ts
│ ├── customer.reducer.ts
│ ├── customer.selectors.ts
│
├── orders/
├── shared/
└── index.ts
Performance Best Practices
| Practice | Benefit |
|---|---|
| Split state into feature stores | Better scalability |
| Keep Store normalized | Faster updates |
| Use Selectors | Memoization |
| Combine with Signals | Cleaner templates |
| Use OnPush | Better rendering |
| Keep state immutable | Predictable behavior |
| Avoid duplicate state | Simpler architecture |
| Use DevTools | Easier debugging |
Common Mistakes
Modifying Store Directly
❌ Wrong
this.store.customers.push(customer);
Always dispatch an Action.
Storing Everything
Do not store temporary UI state like:
- Dialog open flags
- Hover state
- Form focus
Prefer Signals or component-local state for transient UI data.
Duplicate Data
Avoid storing the same information multiple times.
Instead,
derive values using Selectors.
Large Global Store
Split into feature slices.
Example
- Auth
- Customer
- Orders
- Products
Skipping Selectors
Never expose raw Store internals to components.
Selectors provide abstraction and memoization.
Store vs Service
| Feature | Service | NgRx Store |
|---|---|---|
| Global State | Limited | Excellent |
| Predictable Updates | Limited | Excellent |
| Time Travel Debugging | No | Yes |
| Immutable State | Optional | Required |
| Enterprise Applications | Moderate | Excellent |
Advantages
| Feature | Benefit |
|---|---|
| Centralized State | Single source of truth |
| Immutable Updates | Predictable behavior |
| Feature Stores | Modular architecture |
| Selectors | Efficient state access |
| Signals Integration | Modern reactive UI |
| DevTools | Excellent debugging |
Top 10 NgRx Store Interview Questions
1. What is the NgRx Store?
Answer
NgRx Store is a centralized state container that holds application state and provides a predictable, unidirectional data flow.
2. Why is the Store called the Single Source of Truth?
Answer
Because shared application state exists in one centralized location, ensuring consistency across all components and features.
3. Can components modify Store data directly?
Answer
No.
Components dispatch Actions.
Reducers update the Store.
4. Why is Store state immutable?
Answer
Immutability enables predictable updates, easier debugging, memoized selectors, and efficient change detection.
5. What is a Feature Store?
Answer
A Feature Store manages state for a specific feature such as Authentication, Customers, Orders, or Products.
6. How do components read Store data?
Answer
Components read Store data through Selectors, typically using store.select(...) or by converting selector output into Signals with toSignal().
7. Can NgRx Store work with Signals?
Answer
Yes.
Selectors can be converted into Signals, allowing Angular templates to use Signal-based reactivity while the Store remains the centralized source of truth.
8. What should be stored in the Store?
Answer
Store shared application state such as authentication, customers, orders, products, user preferences, and other business data that multiple parts of the application use.
9. What should NOT be stored in the Store?
Answer
Avoid storing temporary UI state such as dialog visibility, hover state, form focus, or short-lived component-specific values.
10. What is the recommended enterprise architecture?
Answer
Use:
- Feature Stores
- Immutable state
- Selectors
- Effects
- Signals for local template reactivity
- OnPush Change Detection
- NgRx DevTools for debugging
Interview Cheat Sheet
| Requirement | Recommended Solution |
|---|---|
| Global State | NgRx Store |
| Feature State | Feature Stores |
| State Updates | Reducers |
| State Reads | Selectors |
| Async Work | Effects |
| UI Reactivity | Signals |
| Rendering | OnPush |
| Debugging | NgRx DevTools |
| State Rules | Immutable |
| Enterprise Apps | NgRx Store + Signals |
Summary
The NgRx Store is the foundation of state management in enterprise Angular applications. By providing a single source of truth, enforcing immutable state, and using Actions, Reducers, and Selectors, it creates predictable and maintainable applications. Modern Angular further enhances this approach by integrating Signals with Store selectors, giving developers a clean and reactive way to consume global state while preserving NgRx's robust architecture.
Key Takeaways
- ✔ NgRx Store is the centralized state container.
- ✔ Components never modify Store state directly.
- ✔ Actions describe changes, while Reducers update state.
- ✔ Feature Stores improve modularity and scalability.
- ✔ Selectors provide efficient, memoized state access.
- ✔ Keep Store state immutable.
- ✔ Store only shared business state.
- ✔ Use Signals for cleaner template reactivity.
- ✔ Combine NgRx Store with OnPush for better performance.
- ✔ NgRx Store is a core Angular enterprise architecture topic and a common interview subject.
Next Article
➡️ 98-NgRx-Actions-QA.md