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.


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