AfterRenderEffect

Angular 19

Doron Azulay

Lifecycle hooks

  • OnInit
  • OnDestroy
  • DoCheck
  • OnChanges
  • AfterContentInit
  • AfterContentChecked
  • AfterViewInit
  • AfterViewChecked

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

  • Computed()
  • LinkedSignal()
  • Resource()
  • Effect()
  • toObservable() - Effect under the hood

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

  • Precise timing after Angular finishes rendering.
  • Perfect for DOM measurements, animations, and 3rd-party orchestration.
  • Browser only (no SSR).
  • Values propagate between phases as signals.

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

  • Phases run once initially.
  • Re-run only when signal dependencies change (dirty).
  • Dependencies can come from: previous-phase signals or component signals.
  • If the value is identical to the previous run, the next phase won’t execute again.

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

  • Use effect() — for most logic reacting to signals or state.
  • Use afterRenderEffect() — rarely, only for low-level DOM tasks or library integrations.

 

It's similar in importance to ngAfterViewInit — powerful but not for everyday code.

AfterRenderEffect

By Doron Azulay

AfterRenderEffect

  • 8