Han sido muchas las novedades que se han escuchado sobre Angular, y entre ellas destacan los Signals. Aunque esta funcionalidad comenzó a implementarse en versiones anteriores a la 19, muchas de sus capacidades se han ido refinando gracias a los comentarios y la retroalimentación de la comunidad.
Con Angular 19, se percibe un cambio en la forma de verlo: más moderno, más accesible. Por eso, es importante empezar a hablar de estos conceptos clave que están cambiando las reglas del juego, y sobre todo la curva de aprendizaje, considerada compleja, desde una perspectiva más amigable y fácil de adoptar para los nuevos entusiastas en Angular.
Pero… ¿qué son los Signals?
Los Signals son una forma sencilla de manejar la reactividad en Angular. En otras palabras, es manejar su estado, permitiéndole reaccionar y observar los cambios de una forma más eficiente de como se hacía con Input/Output o con RxJS.
Según la documentación oficial de Angular, un Signal es como un wrapper (o contenedor), alrededor de un valor, que permite crear, leer y actualizar el valor, mientras Angular se encarga de detectar y propagar los cambios de forma automática.
¿Cómo funcionan los Signals?
En palabras simples, un Signal es como una función que llamas para leer el valor actual de un dato reactivo. Angular utiliza esta lectura para rastrear automáticamente en qué lugares se está usando ese valor, lo que le permite saber cuándo debe actualizarse la vista o ejecutar lógica adicional según el contexto en el que se esté utilizando.
Tipos de Signals
- Writable Signals o Signals modificables
Se permite el uso de Signals para cambiar directamente un valor:
const count = signal(0);
count.set(3); // Asigna directamente
count.update(value => value + 1); // Actualiza basado en el valor anterior
- Computed o Signals derivados
Son de solo lectura porque no tienen un set o update, se derivan de otros Signals, por lo que actualizan su valor basado en otros. Angular se encarga de su re-evaluación de forma perezosa (lazily) y memorizada (memoized).
const count = signal(5);
const doubleCount = computed(() => count() * 2);
Funciones reactivas relacionadas
- Effects o Efectos
Los effects ejecutan lógica cuando cambian uno o más Signals. Son útiles para efectos secundarios como logs, sincronización con localStorage, o actualizaciones manuales del DOM.
effect(() => {
console.log(`El contador actual es: ${count()}`);
});
- afterRenderEffect
Una novedad interesante en Angular 19 y función experimental, diseñada para manejar efectos secundarios después de que el componente haya terminado de renderizar.
A diferencia de effect(), que se ejecuta durante el ciclo de detección de cambios, afterRenderEffect() espera a que el DOM se haya actualizado para ejecutar la lógica, lo cual es muy útil cuando necesitas interactuar con elementos renderizados.
afterRenderEffect(() => {
console.log('after render effect', this.counter());
});
Buenas prácticas
Los Signals son poderosos, pero también requieren atención a ciertos detalles para usarlos correctamente y evitar errores comunes:
- Contexto de inyección
effect() solo puede ejecutarse dentro de un contexto de inyección. Eso significa que deberías declararlo dentro del constructor de un componente, servicio o directiva donde inject() esté disponible. Alternativamente, puedes guardarlo como una propiedad privada.
@Component({...})
export class MyComponent {
count = signal(0);
constructor() {
effect(() => {
console.log(this.count());
});
}
}
- Limpieza de efectos
Cuando creas un efecto, Angular lo destruye automáticamente al destruir su contexto. Si hay un efecto que deba ser destruido manualmente, puedes usar .destroy() con la opción manualCleanup.
const myEffect = effect(() => {
// ...
}, { manualCleanup: true });
myEffect.destroy();
- Limpieza dentro del efecto
Si usas temporizadores setTimeout, suscripciones subscriptions, o cualquier recurso que permanezca activo, aplica onCleanup() para liberar recursos y limpiarlos, antes de que el efecto vuelva a ejecutarse o se destruya.
effect((onCleanup) => {
const timer = setTimeout(() => {
console.log('1 segundo después');
}, 1000);
onCleanup(() => clearTimeout(timer));
});
Ejemplo práctico: signals en un chat de recetas
Como ejercicio práctico, he creado un chat de recetas utilizando Angular con signals. Este ejemplo demuestra cómo gestionar el estado de la conversación de forma reactiva y sencilla, integrando además la respuesta de un modelo generativo.
Puedes explorar el proyecto completo en el siguiente enlace:
cookies-chat-recipe
Conclusión
Angular seguirá en cada versión trayéndonos nuevas mejoras a todas sus funcionalidades y ha marcado un antes y un después con Signals, simplificando la reactividad, mejorando el rendimiento y haciendo más amigable la curva de aprendizaje.
Vale la pena explorarlos, probarlos, y comenzar a integrarlos en tus componentes para mejorar el rendimiento de tus aplicaciones y sacar provecho a estas nuevas funcionalidades.
Top comments (0)