Cuando un componente tiene OnPush, solo se actualizará si ocurre alguna de estas situaciones:
1️⃣ Cambio en un @Input()
Si el valor del @Input() cambia de referencia, Angular actualizará el componente.
✅ Se actualiza porque cambia la referencia (objeto nuevo)
this.producto = { nombre: 'Nuevo Producto' };
// Esto genera una nueva referencia en memoria❌ No se actualiza si solo se modifica una propiedad interna
this.producto.nombre = 'Nuevo Producto';
// No cambia la referencia del objeto en memoria, Angular no lo detecta💡 Solución: Para forzar la detección de cambios, asigna un nuevo objeto:
this.producto = { ...this.producto, nombre: 'Nuevo Producto' };2️⃣ Eventos del DOM (click, input, etc.)
Si el componente tiene un evento como (click), (input), (change), etc., Angular detectará el cambio.
(click)="cambiarValor()">ActualizarcambiarValor() {
this.valor = 'Nuevo';
}Esto siempre actualizará la vista, incluso con OnPush.
3️⃣ Uso de async en un | async pipe (Observables)
Si usas el pipe async, Angular actualizará automáticamente el componente cuando el Observable emita un nuevo valor.
{{ datos$ | async }}datos$ = this.http.get('https://api.example.com/data');
4️⃣ Cambios manuales con markForCheck()
Si necesitas actualizar manualmente el componente, puedes usar ChangeDetectorRef.markForCheck().
constructor(private cd: ChangeDetectorRef) {}
actualizar() {
this.valor = 'Nuevo';
this.cd.markForCheck(); // 🔥 Forzar actualización
}
5️⃣ Cambio en una variable dentro de un setTimeout o setInterval
Si modificamos una variable dentro de setTimeout, Angular no lo detectará a menos que usemos markForCheck().
❌ No se actualiza automáticamente
setTimeout(() => {
this.valor = 'Nuevo';
}, 2000);✅ Solución con markForCheck()
setTimeout(() => {
this.valor = 'Nuevo';
this.cd.markForCheck();
}, 2000);6️⃣ Cambios después de una petición HTTP manual
Si asignamos un nuevo valor después de una petición HTTP sin async, Angular no lo detectará automáticamente.
❌ No se actualiza automáticamente
this.http.get('https://api.example.com/data').subscribe(data => {
this.valor = data;
});✅ Solución con markForCheck()
this.http.get('https://api.example.com/data').subscribe(data => {
this.valor = data;
this.cd.markForCheck();
});
7️⃣ Re-adjuntar la detección de cambios con reattach()
Si en algún momento se desactiva la detección de cambios con cd.detach(), podemos volver a activarla con reattach().
this.cd.detach(); // 🛑 Detiene la detección
this.cd.reattach(); // 🔄 Reactiva la detección📌 Resumen final
Si un componente tiene OnPush, solo se actualizará cuando ocurra alguno de estos eventos:
| Evento | ¿Actualiza con OnPush? |
|---|---|
Cambio en un @Input() (nueva referencia) |
✅ Sí |
Evento del DOM (click, input, etc.) |
✅ Sí |
async pipe con Observables |
✅ Sí |
Uso de markForCheck()
|
✅ Sí |
setTimeout o setInterval
|
❌ No (a menos que uses markForCheck()) |
HTTP Request (subscribe()) |
❌ No (a menos que uses markForCheck()) |
detach() |
❌ No |
reattach() |
✅ Sí |
🎯 Conclusión
🔹 OnPush mejora el rendimiento porque evita que Angular revise el componente en cada ciclo de cambio.
🔹 Sin embargo, sigue actualizándose en situaciones clave como cambios en @Input, eventos del DOM o usando markForCheck().
🔹 Si necesitas forzar un cambio manualmente, usa markForCheck() o detectChanges().
Ahora tienes el conocimiento completo sobre OnPush y cuándo se actualizan los componentes. 🚀🔥