Angular Signals: A New Reactive Foundation for Modern Angular Apps
Angular has always been a powerful framework, but it has also been criticized for being complex, verbose, and difficult to reason about…
Angular Signals: A New Reactive Foundation for Modern Angular Apps
Angular has always been a powerful framework, but it has also been criticized for being complex, verbose, and difficult to reason about when state grows. Over the years, Angular relied heavily on Zone.js, change detection cycles, and RxJS to manage reactivity.
With Angular 16, the framework introduced Signals — a fundamental shift in how Angular thinks about state and reactivity.
Signals are not just a new API. They represent a new mental model for Angular developers.
This article provides a deep introduction to Signals:
- Why Angular needed them
- What problems they solve
- How they work internally (conceptually)
- How they differ from RxJS and traditional change detection
- When (and when not) to use them
The Problem with Traditional Angular Reactivity
Before Signals, Angular relied on change detection triggered by:
- User events
- HTTP responses
- Timers
- Zone.js patching async APIs
Traditional Flow
- Something changes (click, HTTP response, timer)
- Zone.js notJS triggers change detection
- Angular checks the entire component tree
- Bindings are re-evaluated
- UI updates
This approach worked, but it had drawbacks:
Key Issues
❌ Over-checking Angular often checks more components than necessary.
❌ Hidden dependencies It’s not always clear what caused a view to update.
❌ Boilerplate Using RxJS for simple UI state leads to:
- Subjects
- Subscriptions
- Unsubscriptions
- Async pipes everywhere
❌ Mental overhead Developers must constantly think about:
- When change detection runs
- OnPush strategies
- Manual optimizations
Angular needed a simpler, more explicit reactive primitive.
What Exactly Is a Signal?
A Signal is a reactive value container that:
- Holds a value
- Tracks who reads it
- Notifies dependents when the value changes
Think of a signal as: “A value that knows who depends on it.”
Creating a Signal
import { signal } from '@angular/core';
const counter = signal(0);
Reading Signal
counter(); // 0
Writing a Signal
counter.set(5);
counter.update(v => v + 1);
Why Are Signals Functions?
This is a common question.
Angular uses function calls because:
- It allows Angular to track dependencies automatically
- It avoids proxies and magic getters
- It makes reads explicit
When Angular sees:
counter();
It knows: “This code depends on counter.”
That dependency is registered automatically.
Fine-Grained Reactivity: The Core Idea
Signals enable fine-grained reactivity, meaning:
- Only code that actually depends on a signal will re-run
- No full component tree re-checks
- No guessing which component changed
Example
const firstName = signal('Sameer');
const lastName = signal('Shukla');
const fullName = computed(() => `${firstName()} ${lastName()}`)
If firstName changes:
fullNameupdates- Anything using
fullName()updates - Nothing else runs
This is fundamentally different from classic Angular CD.
Computed Signals: Derived State Done Right
Computed signals allow you to derive state without storing redundant data.
import { computed } from '@angular/core';
const price = signal(100);
const quantity = signal(3);
const total = computed(() => price() * quantity());
Why This Is Powerful
- Automatically recalculates
- Memoized (cached)
- Recomputes only when dependencies change
- No manual subscriptions
This replaces many use cases of:
map()combineLatest()- Getter functions in components
Effects: Reacting to Changes
Signals are about state, but sometimes you need side effects:
- Logging
- Local storage
- API calls
- DOM interactions
That’s where effect() comes in.
import { effect } from '@angular/core';
effect(() => {
console.log('Total changed:', total());
});
Whenever total changes:
- The effect re-runs automatically
Important Rule
❗ Effects should not modify signals they depend on Doing so can cause infinite loops.
Signals in Angular Components
Signals integrate directly with templates.
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">+</button>
<p>Count: {{ count() }}</p>
`
})
export class CounterComponent {
count = signal(0);
increment() {
this.count.update(v => v + 1);
}
}
What’s Missing?
- No
ChangeDetectorRef - No
asyncpipe - No subscriptions
- No
OnPushcomplexity
Angular automatically knows what to update and when.
Signals vs RxJS: A Clear Boundary
Signals often get compared to Observables, but they solve different problems.
Signals Are Best For
✔ UI state ✔ Local component state ✔ Derived values ✔ Shared synchronous state
RxJS Is Best For
✔ HTTP calls ✔ WebSocket streams ✔ Events over time ✔ Complex async flows
Angular’s recommendation: Use RxJS for async, Signals for state.
Signals Without Zone.js
One of the long-term goals of Signals is to make Angular less dependent on Zone.js.
Because Angular knows:
- Which signals changed
- Who depends on them
It can update views without global change detection cycles.
This enables:
- Better performance
- Better SSR
- Easier mental model
Conclusion
Signals represent the most important change in Angular’s reactivity since its inception.
They:
- Simplify state management
- Reduce boilerplate
- Improve performance
- Make Angular more predictable and modern
Signals are not just a feature — they are Angular’s future reactive foundation.
메타데이터
- post_id
- 964ddd2a7567
- slug
- angular-signals-a-new-reactive-foundation-for-modern-angular-apps-964ddd2a7567
- url
- https://medium.com/@ss.web/angular-signals-a-new-reactive-foundation-for-modern-angular-apps-964ddd2a7567
- canonical_url
- https://medium.com/@ss.web/angular-signals-a-new-reactive-foundation-for-modern-angular-apps-964ddd2a7567
- author_url
- https://medium.com/@ss.web
- status
- ok
- fetched_at
- 2026-06-09 15:37:30