Angular Signals: ¿El Nuevo Estándar para la Gestión de Estado?
La gestión de estado en aplicaciones Angular ha sido tradicionalmente dominada por RxJS y sus Observables. Sin embargo, con la llegada de Angular Signals, el panorama está cambiando rápidamente. ¿Es este el nuevo estándar que estábamos esperando?
Tabla de contenido
El Problema Actual con la Gestión de Estado
Si has trabajado con Angular, probablemente te has encontrado con código como este:
export class UserService {
private userSubject = new BehaviorSubject<User | null>(null);
user$ = this.userSubject.asObservable();
updateUser(user: User) {
this.userSubject.next(user);
}
}
@Component({
template: `
<div *ngIf="user$ | async as user">
{{ user.name }}
</div>
`
})
export class UserComponent implements OnDestroy {
user$ = this.userService.user$;
private subscription: Subscription;
constructor(private userService: UserService) {
this.subscription = this.user$.subscribe(/* ... */);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Este enfoque presenta varios desafíos:
- Gestión manual de suscripciones
- Posibles memory leaks
- Código repetitivo
- Complejidad innecesaria
Signals: La Alternativa Moderna
Angular Signals introduce una forma más simple y eficiente de manejar el estado:
export class UserService {
private user = signal<User | null>(null);
updateUser(user: User) {
this.user.set(user);
}
getUser() {
return this.user;
}
}
@Component({
template: `
<div *ngIf="user()">
{{ user().name }}
</div>
`
})
export class UserComponent {
user = this.userService.getUser();
constructor(private userService: UserService) {}
// ¡No necesitas ngOnDestroy!
}
La API de Angular Signals es bastante intuitiva para manejar el estado. Veamos sus métodos principales:
1. Creación de Signals
// Signal básico
const count = signal<number>(0); // Valor inicial: 0
const user = signal<User | null>(null); // Puede ser nullable
const settings = signal<Settings>({theme: 'dark'}); // Objetos complejos
// Signal computado (depende de otros signals)
const doubleCount = computed(() => count() * 2);
2. Acceso al Valor
// Lectura simple
console.log(count()); // Obtiene el valor actual: 0
// En template
@Component({
template: `
<div>Contador: {{ count() }}</div>
<div>Doble: {{ doubleCount() }}</div>
`
})
3. Modificación de Valores
// Actualización directa
count.set(5); // Establece un nuevo valor
// Actualización basada en valor anterior
count.update(value => value + 1); // Incrementa en 1
// Mutación de objetos
const todos = signal<Todo[]>([]);
todos.mutate(value => {
value.push({ id: 1, text: 'Nueva tarea' });
});
Signals vs RxJS: ¿Cuál Usar?
Característica | Signals | RxJS |
Sintaxis | Simple y directa | Más verbosa |
Manejo de memoria | Automático | Manual |
Operaciones complejas | Básicas | Muy complejas |
Curva de aprendizaje | Baja | Alta |
Casos de uso | Estado simple y UI | Streams complejos |
Beneficios Inmediatos de Signals
1. Código más Limpio
- No más suscripciones manuales
- Sin necesidad de operadores pipe
- Sintaxis más intuitiva
2. Mejor Rendimiento
- Actualizaciones granulares
- Menos sobrecarga de memoria
- Sin necesidad de ciclos de detección de cambios adicionales
3. Seguridad de Tipos
// Con Signals
const count = signal<number>(0);
count.set('1'); // Error de TypeScript
// Con RxJS
const count$ = new BehaviorSubject(0);
count$.next('1'); // Sin error de TypeScript
¿Cuándo Migrar a Signals?
Signals es ideal para:
- Componentes con estado simple
- UI reactiva
- Aplicaciones nuevas en Angular 16+
Mantén RxJS para:
- Operaciones asíncronas complejas
- Transformaciones de datos elaboradas
- Integración con librerías existentes
Conclusión
Angular Signals representa un paso significativo hacia una gestión de estado más simple y eficiente. Aunque no reemplaza completamente a RxJS, ofrece una alternativa más limpia para muchos casos de uso comunes.
Para empezar, considera migrar gradualmente componentes simples a Signals mientras mantienes RxJS para operaciones más complejas. La combinación de ambos enfoques puede dar lugar a aplicaciones más mantenibles y eficientes.
¿Quieres aprender más? Consulta la documentación oficial de Angular Signals para profundizar en el tema o puedes leer el anterior artículo sobre TypeScript.