Angular Signals: A Practical Introduction
If you’ve been working with Angular for a while, you’ve probably heard about signals by now. They shipped as stable in Angular 17 and have quietly changed how we think about reactivity in the framework.
What Problem Do They Solve?
The original Angular change detection model is powerful but blunt. When something changes, Angular runs ChangeDetectionStrategy.Default down the entire component tree. Even with OnPush, you’re still working with Observables and manually triggering checks in places.
Signals introduce fine-grained reactivity — Angular knows exactly which values changed and which templates need to re-render. No more scanning the whole tree.
The Basics
A signal is just a reactive value wrapper:
import { signal, computed, effect } from '@angular/core'
const count = signal(0)
// Read
console.log(count()) // 0
// Write
count.set(1)
count.update(v => v + 1)
// Derived
const double = computed(() => count() * 2)
// Side effects
effect(() => {
console.log('Count changed:', count())
})
In a Component
@Component({
template: `<p>{{ count() }} — {{ double() }}</p>`
})
export class CounterComponent {
count = signal(0)
double = computed(() => this.count() * 2)
increment() { this.count.update(v => v + 1) }
}
No subscribe(). No async pipe. No manual unsubscription.
When to Use Them
Signals shine for:
- Local component state
- Derived values that depend on other signals
- Replacing simple
BehaviorSubjectpatterns
Keep RxJS for:
- HTTP requests
- Complex async workflows
- Time-based operations
The two work well together — toSignal() and toObservable() bridge them cleanly.
The Bottom Line
Signals are not a replacement for Angular’s entire reactivity model. They’re a better primitive for synchronous, local state. Start small — pick one component and replace its local state with signals. You’ll feel the difference immediately.
Angular Signals: Introducción Práctica
Si venís trabajando con Angular hace un tiempo, seguro ya escuchaste hablar de los signals. Llegaron como estables en Angular 17 y cambiaron silenciosamente cómo pensamos la reactividad en el framework.
¿Qué Problema Resuelven?
El modelo original de detección de cambios de Angular es poderoso pero grueso. Cuando algo cambia, Angular recorre todo el árbol de componentes con ChangeDetectionStrategy.Default. Incluso con OnPush, seguís trabajando con Observables y disparando checks manualmente en varios lugares.
Los Signals introducen reactividad de grano fino — Angular sabe exactamente qué valores cambiaron y qué templates necesitan re-renderizarse. Sin más escaneos del árbol completo.
Lo Básico
Un signal es simplemente un wrapper reactivo para un valor:
import { signal, computed, effect } from '@angular/core'
const count = signal(0)
// Leer
console.log(count()) // 0
// Escribir
count.set(1)
count.update(v => v + 1)
// Derivado
const double = computed(() => count() * 2)
// Efectos secundarios
effect(() => {
console.log('Count cambió:', count())
})
En un Componente
@Component({
template: `<p>{{ count() }} — {{ double() }}</p>`
})
export class CounterComponent {
count = signal(0)
double = computed(() => this.count() * 2)
increment() { this.count.update(v => v + 1) }
}
Sin subscribe(). Sin pipe async. Sin desuscripción manual.
Cuándo Usarlos
Los signals brillan para:
- Estado local del componente
- Valores derivados que dependen de otros signals
- Reemplazar patrones simples con
BehaviorSubject
Mantené RxJS para:
- Requests HTTP
- Flujos async complejos
- Operaciones basadas en tiempo
Los dos trabajan bien juntos — toSignal() y toObservable() los conectan limpiamente.
La Conclusión
Los Signals no son un reemplazo del modelo de reactividad completo de Angular. Son una mejor primitiva para el estado local y sincrónico. Empezá de a poco — elegí un componente y reemplazá su estado local con signals. Vas a sentir la diferencia de inmediato.