Debido a la complejidad de la programación reactiva la curva de aprendizaje se vuelve demasiado compleja y abrumadora para personas que quieren iniciar con Angular, pero esto está a punto de cambiar
- Que es la reactividad de grano fino
- Como funcionan los signals
- Qué diferencia tiene de RxJs
- Como ayuda a facilitar el uso de Angular
Que es el manejo de estado de grano fino
La reactividad de grano fino es un paradigma de programación que permite la reevaluación automática del código en respuesta a cambios en los datos o el estado. En este paradigma, el código se divide en pequeñas unidades reactivas independientes que son sensibles a los cambios en sus datos de entrada. Cuando los datos de entrada cambian, estas unidades reactivas se vuelven a evaluar automáticamente, actualizando su salida en consecuencia.
La reactividad de grano fino se usa comúnmente en frameworks de programación como Solid.js, Vue.js y Svelte y parcialmente Angular, donde la interfaz de usuario se actualiza automáticamente en respuesta a los cambios en los datos subyacentes. En estos frameworks, los componentes de la interfaz de usuario se definen como unidades reactivas que se vuelven a evaluar en respuesta a los cambios en el estado de la aplicación.
La reactividad de grano fino puede mejorar el rendimiento y la capacidad de mantenimiento de aplicaciones complejas al reducir la necesidad de actualizaciones manuales de la interfaz de usuario y permitir un procesamiento de datos más eficiente. También puede ayudar a garantizar que la interfaz de usuario de la aplicación se mantenga coherente con los datos subyacentes en todo momento, lo que mejora la experiencia del usuario.
Como funcionan los signals
Imaginemos que tenemos una variable que contiene un valor así como las de toda la vida, lo interesante radica en que si el signal cambia también cambiará todo lo que de ese signal esto ahorra tiempos y recursos, ya que de esta manera no se consulta todo el árbol de componente para poder determinar si hay un cambio por ejemplo
Angular clásico:
@Component({
template: `
{{ personas }}
<button (click)="agregarPersonas()">Agregar personas</button>
`,
})
export class AppComponent {
personas = 0;
agregarPersonas() {
this.personas = 5;
}
}Usando Signals:
import { signal, computed } from '@angular/core';
export class AppComponent {
personas = signal(0);
duplicarPersonas = computed(() => this.personas() * 2);
agregarPersonas() {
this.personas.update((count) => count + 1);
}
}Usando RxJS:
personas$ = new BehaviorSubject(0);
duplicarPersonas$ = this.personas$.pipe(map((personas) => personas * 2));Nota la diferencia: la versión con computed() se lee como una función normal, no necesita suscripción y nunca tiene fugas de memoria. La versión con RxJS necesita un BehaviorSubject, un pipe, y un async pipe o una suscripción manual en la plantilla.
signal() vs. computed(): ¿cuál es la diferencia?
signal() | computed() | |
|---|---|---|
| Valor | Mutable — se asigna directamente | Derivado, de solo lectura |
| Cómo se modifica | .set(valor) o .update(fn) | Se recalcula automáticamente cuando cambian sus dependencias |
| Uso típico | Fuente de verdad para el estado del componente | Valores derivados de uno o más signals |
Qué diferencia tiene de RxJS
La principal diferencia es que RxJS es una biblioteca específica para programación reactiva con streams, mientras que la reactividad de grano fino es un paradigma más general que se puede implementar con distintas técnicas — los signals son la implementación de Angular.
| Signals | Observables (RxJS) | |
|---|---|---|
| Naturaleza | Síncronos, siempre tienen un valor actual | Modelan valores a lo largo del tiempo — pueden ser asíncronos |
| Lectura | Se llaman directamente: personas(), sin suscripción | Requieren subscribe() o el pipe async |
| Ciclo de vida | No completan, no requieren limpieza manual | Pueden completar o dar error; requieren unsubscribe() |
| Ideal para | Estado de componente, valores derivados | Respuestas HTTP, streams de WebSocket, eventos |
No tienes que elegir entre uno u otro. toSignal() y toObservable() de @angular/core/rxjs-interop convierten entre ambos, así que las llamadas HTTP pueden seguir en RxJS mientras el estado de tu plantilla vive en signals.
Como ayuda a facilitar el uso de Angular
Al usar signals, las actualizaciones del DOM se manejan de forma más rápida y precisa. Los signals no son Observables: puedes leer su valor directamente, de forma síncrona, sin suscribirte — sin subscribe(), sin unsubscribe(), sin checklist de fugas de memoria.
Desde Angular 19, los signals son la opción recomendada por defecto para el estado de componente, y son la base sobre la que se construye el framework: la detección de cambios zoneless, los signals input() y Signal Forms se apoyan en este modelo de reactividad.
Ejemplos en vivo:
Los Signals van de la mano con la nueva sintaxis de plantillas — revisa Control Flow en Angular: @if, @for y @switch (Adiós ngIf) para la otra mitad de Angular declarativo.