Angular Local And Shared Component State Complete Guide
Understanding the Core Concepts of Angular Local and Shared Component State
Local Component State
Definition: Local component state refers to the data and properties that are specific to a single component and do not need to be shared with other components. It's encapsulated within the component and typically handled using simple class variables.
Important Info:
Encapsulation:
- Data managed locally is contained within the component’s class. Changes to this state do not affect other parts of the application unless explicitly handled through input/output bindings or service injection.
Lifecycle Hooks:
- Use lifecycle hooks such as
ngOnInit
,ngOnChanges
,ngDoCheck
, andngOnDestroy
to manage initialization, changes detection, and cleanup processes respectively.
- Use lifecycle hooks such as
Reactivity:
- For reactivity within local states, especially when dealing with asynchronous data fetches, use Observables in conjunction with RxJS.
Best Practices:
- Keep the local state as minimal as possible by delegating shared data to services or global state management solutions.
- Use
@Input
and@Output
decorators to interact between parent-child components without directly manipulating their states.
Performance:
- Locally managed states are lightweight and fast because they are tightly scoped to individual components. This reduces unnecessary change detection cycles across the application.
Example:
import { Component } from '@angular/core'; @Component({ selector: 'app-local-component', template: `<div> <p>Counter: {{counter}}</p> <button (click)="incrementCounter()">Increment</button> </div>` }) export class LocalComponent { counter = 0; incrementCounter() { this.counter++; } }
Shared Component State
Definition: Shared component state involves data that needs to be accessible by multiple components. This could range from sibling components to distant relatives, and it often requires more sophisticated state management techniques.
Important Info:
Services:
- Services are the most common way to share state between components in Angular. They are singleton instances that can be injected across multiple components.
RxJS Observables:
- Utilize RxJS Observables and Subjects (like BehaviorSubject, ReplaySubject) to facilitate communication and state updates between components in response to changing data.
BehaviorSubject:
- A BehaviorSubject holds the current value and emits that value whenever it is subscribed to, making it ideal for handling shared state.
Store and Reducers:
- Consider using NgRx Store if your application has complex state requirements that involve numerous interrelated components. NgRx uses a centralized store and reducers to manage state transitions.
Local Storage and Session Storage:
- For persistence across page reloads, you can use local storage or session storage to save and retrieve shared state, although this is less preferred for state management within Angular.
State Management Libraries:
- Libraries like Akita, NgRx, and Redux Store provide advanced mechanisms for managing shared state. They support features such as immutable state, side effects, and time-travel debugging.
Best Practices:
- Abstract business logic and state management out of components and place them into dedicated services.
- Use immutable state patterns to avoid unintended side effects and enhance performance.
- Implement state slices where possible to divide a large global state into smaller, manageable parts.
Example with a Service:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SharedStateService { private _sharedData = new BehaviorSubject<any>(null); sharedData$ = this._sharedData.asObservable(); updateSharedData(data: any) { this._sharedData.next(data); } }
Usage in components:
Online Code run
Step-by-Step Guide: How to Implement Angular Local and Shared Component State
1. Local Component State
Step 1: Setting Up an Angular Project
First, let's create a new Angular project if you haven't already.
ng new local-state-demo
cd local-state-demo
Step 2: Generating a Component
Create a new component where we'll manage local state.
ng generate component counter
Step 3: Implementing Local State
Edit the counter.component.ts
file to manage local state using a class property.
// src/app/counter/counter.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.css']
})
export class CounterComponent {
count: number = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
Step 4: Creating a Template
Edit the counter.component.html
file to add buttons and display the count.
<!-- src/app/counter/counter.component.html -->
<div>
<h2>Local State Counter</h2>
<p>Current Count: {{ count }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
</div>
Step 5: Adding the Component to App Module
Make sure the CounterComponent
is declared in your app.module.ts
.
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CounterComponent } from './counter/counter.component';
@NgModule({
declarations: [
AppComponent,
CounterComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 6: Displaying the Component
Add the app-counter
selector to your app.component.html
to display the counter component.
<!-- src/app/app.component.html -->
<div style="text-align:center">
<app-counter></app-counter>
</div>
Step 7: Running the Application
Run the Angular application to see the local state in action.
ng serve
Navigate to http://localhost:4200
in your browser. You should see a counter with buttons to increment and decrement the count.
2. Shared Component State
Step 1: Creating a Shared State Service
To share state between multiple components, we'll create a service.
ng generate service shared-state
Step 2: Implementing Shared State Service
Edit the shared-state.service.ts
file to manage a shared state property.
// src/app/shared-state.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SharedStateService {
private countSubject = new BehaviorSubject<number>(0);
count$ = this.countSubject.asObservable();
increment() {
this.countSubject.next(this.countSubject.value + 1);
}
decrement() {
this.countSubject.next(this.countSubject.value - 1);
}
}
Step 3: Creating Multiple Components
Generate two new components to demonstrate shared state.
ng generate component shared-counter1
ng generate component shared-counter2
Step 4: Implementing Components to Use Shared State
Edit the shared-counter1.component.ts
file to use the shared state service.
// src/app/shared-counter1/shared-counter1.component.ts
import { Component, OnInit } from '@angular/core';
import { SharedStateService } from '../shared-state.service';
@Component({
selector: 'app-shared-counter1',
templateUrl: './shared-counter1.component.html',
styleUrls: ['./shared-counter1.component.css']
})
export class SharedCounter1Component implements OnInit {
count: number = 0;
constructor(private sharedStateService: SharedStateService) {}
ngOnInit(): void {
this.sharedStateService.count$.subscribe(count => this.count = count);
}
increment() {
this.sharedStateService.increment();
}
decrement() {
this.sharedStateService.decrement();
}
}
Edit the shared-counter1.component.html
file to add buttons and display the count.
<!-- src/app/shared-counter1/shared-counter1.component.html -->
<div>
<h2>Shared State Counter 1</h2>
<p>Current Count: {{ count }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
</div>
Now, edit the shared-counter2.component.ts
file to use the shared state service.
// src/app/shared-counter2/shared-counter2.component.ts
import { Component, OnInit } from '@angular/core';
import { SharedStateService } from '../shared-state.service';
@Component({
selector: 'app-shared-counter2',
templateUrl: './shared-counter2.component.html',
styleUrls: ['./shared-counter2.component.css']
})
export class SharedCounter2Component implements OnInit {
count: number = 0;
constructor(private sharedStateService: SharedStateService) {}
ngOnInit(): void {
this.sharedStateService.count$.subscribe(count => this.count = count);
}
increment() {
this.sharedStateService.increment();
}
decrement() {
this.sharedStateService.decrement();
}
}
Edit the shared-counter2.component.html
file to add buttons and display the count.
<!-- src/app/shared-counter2/shared-counter2.component.html -->
<div>
<h2>Shared State Counter 2</h2>
<p>Current Count: {{ count }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
</div>
Step 5: Adding Components to App Module
Ensure the SharedCounter1Component
and SharedCounter2Component
are declared in your app.module.ts
.
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CounterComponent } from './counter/counter.component';
import { SharedCounter1Component } from './shared-counter1/shared-counter1.component';
import { SharedCounter2Component } from './shared-counter2/shared-counter2.component';
@NgModule({
declarations: [
AppComponent,
CounterComponent,
SharedCounter1Component,
SharedCounter2Component
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 6: Displaying the Components
Add the app-shared-counter1
and app-shared-counter2
selectors to your app.component.html
to display the shared counter components.
<!-- src/app/app.component.html -->
<div style="text-align:center">
<app-shared-counter1></app-shared-counter1>
<app-shared-counter2></app-shared-counter2>
</div>
Step 7: Running the Application
Run the Angular application to see the shared state in action.
ng serve
Navigate to http://localhost:4200
in your browser. You should see two counters with buttons to increment and decrement the count. Both counters will reflect the same state, demonstrating shared state management.
Login to post a comment.