AfterRenderEffect
Angular 19
Doron Azulay
Lifecycle hooks
Constructor / OnInit
Components should be cheap and safe to constructor.
You should not, for example - fetch data in component constructor.
ngOnInit() is a better place for a component to fetch initial data.
@Component({/*...*/})
Class UserComponent {
name = input<string>();
constructor(): {
//inputs aren't set yet
}
ngOnInit(): void {
//can read inputs
}
}OnInit Replacements
OnDestroy
Use DestroyRef
export class DemoTakeUntilComponent {
private destroyRef = inject(DestroyRef);
// example 1
constructor() {
interval(1000)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((value) => console.log('Tick:', value));
}
// example 2
const unregisterFn = destroyRef.onDestroy(() => doSomethingOnDestroy());
unregisterFn();
}@Component( ... )
export class FooComponent {
constructor() {
effect(() => { ... })
}
}
Registers an "effect" that will be scheduled & executed whenever the signals that it reads changes.
Use effect()
OnChanges
@Component( ... )
export class FooComponent {
chart = viewChild(MyChart);
constructor() {
afterNextRender(() => {
initChart(...)
})
}
}Run just once!
Replaces:
AfterContentInit,
AfterViewInit
@Component( ... )
export class FooComponent {
chart = viewChild(MyChart);
constructor() {
afterRender(() => {
initChart(...)
})
}
}Run every CD cycle
Replaces:
AfterContentCheck
AfterViewCheck
AfterContentInit / AfterContentChecked
Use afterNextRender / afterRender
AfterViewInit / AfterViewChecked
Use afterRenderEffect()
@Component( ... )
export class FooComponent {
constructor() {
afterRenderEffect({
earlyRead: () => {...},
read: () => {...},
mixedReadWrite: () => {...}
write: () => {...}
});
}
}
Live Coding
AfterRenderEffect
Post-Render Reactivity in Angular
Phased Execution
Prefer read/wite over earlyRead/mixedReadWrite
| Phase | Rule |
|---|---|
| earlyRead | Read from DOM. Never write here. |
| write | Write to DOM. Never read here. |
| mixedReadWrite | Read + write (use sparingly). |
| read | Final DOM reads after writes. |
| Lifecycle Hook | Replacement |
|---|---|
| ngOnInit | effect() |
| ngOnChanges | effect() |
| ngAfterViewInit | afterRenderEffect() |
| ngAfterViewChecked | afterRenderEffect() |
afterRenderEffect({
earlyRead: () => X,
write: (xSignal) => Y,
mixedReadWrite: (ySignal) => Z},
read: (zSignal) => {...}
});Selective Re-Execution
effect() vs afterRenderEffect()
| Aspect | effect() | afterRenderEffect() |
|---|---|---|
| Purpose | General reactive state | Post-render DOM operations |
| Timing | During change detection | After rendering finishes |
| Use Cases | Signal/data reactions | Measurements, animations, 3rd‑party libs |
| Execution | Re-runs on signal change | Phased; reruns when “dirty” |
| SSR | Supported | Browser only |
| Lifecycle analog | OnInit/OnChanges | AfterViewInit/AfterViewChecked |
When to use
It's similar in importance to ngAfterViewInit — powerful but not for everyday code.