Angular calls a set of lifecycle hook methods on components and directives at specific moments — during creation, every change detection cycle, and finally before destruction. Implementing the corresponding interface (e.g. OnInit, OnDestroy) is optional but recommended for type safety.
1. constructor vs. ngOnInit
The constructor is a TypeScript feature, not an Angular lifecycle hook. Angular calls it before inputs are set, so @Input() values are undefined at that point.
@Component({ selector: 'app-card', template: '' })
export class CardComponent implements OnInit {
@Input() title = '';
constructor() {
console.log(this.title); // always '' — input not yet set
}
ngOnInit() {
console.log(this.title); // correct value, inputs are initialized
}
}
Enter fullscreen mode Exit fullscreen mode
Rule: Use the constructor only for dependency injection. Use ngOnInit for any initialization logic that depends on inputs or injected services.
2. Lifecycle hooks in order
ngOnChanges(changes: SimpleChanges)
Runs whenever one or more @Input() values change. On the first render it runs before ngOnInit. The changes argument is a map of input name → SimpleChange object, each containing previousValue, currentValue, and firstChange.
ngOnChanges(changes: SimpleChanges) {
if (changes['title']) {
const { previousValue, currentValue, firstChange } = changes['title'];
console.log(`title changed from "${previousValue}" to "${currentValue}"`);
}
}
Enter fullscreen mode Exit fullscreen mode
Only implements when the component has @Input() properties. Not called if the component has no inputs.
ngOnInit()
Runs once, after all inputs have been set for the first time and ngOnChanges has been called for the first time (if applicable). The component’s own template is not yet rendered at this point, but it is safe to read inputs and call services.
ngOnInit() {
this.data = this.dataService.load(this.id);
}
Enter fullscreen mode Exit fullscreen mode
ngDoCheck()
Runs on every change detection cycle that involves this component — which is very frequent. Use it only when you need to detect changes Angular’s default change detection misses (e.g. mutated object references). Avoid heavy logic here.
ngDoCheck() {
// runs on every CD cycle — keep this extremely lightweight
if (this.items !== this.previousItems) {
this.previousItems = this.items;
this.recompute();
}
}
Enter fullscreen mode Exit fullscreen mode
ngAfterContentInit()
Runs once after Angular projects external content into the component’s <ng-content> slots. This is where you can safely read @ContentChild / @ContentChildren queries.
@ContentChild(HeaderComponent) header!: HeaderComponent;
ngAfterContentInit() {
console.log(this.header); // projected content is available here
}
Enter fullscreen mode Exit fullscreen mode
ngAfterContentChecked()
Runs after every change detection check of the projected content, including the first. Rarely needed — prefer ngAfterContentInit for one-time setup.
ngAfterViewInit()
Runs once after the component’s own template (and all child components within it) has been fully initialized. This is where you can safely read @ViewChild / @ViewChildren queries.
@ViewChild('canvas') canvasRef!: ElementRef<HTMLCanvasElement>;
ngAfterViewInit() {
const ctx = this.canvasRef.nativeElement.getContext('2d');
// safe to access DOM here
}
Enter fullscreen mode Exit fullscreen mode
ngAfterViewChecked()
Runs after every change detection check of the component’s view. Rarely needed. Be careful — modifying component state here can cause ExpressionChangedAfterItHasBeenChecked errors.
ngOnDestroy()
Runs once, just before Angular removes the component from the DOM. Use it to clean up anything that would otherwise cause memory leaks: timers, subscriptions, event listeners.
export class PollingComponent implements OnInit, OnDestroy {
private intervalId!: ReturnType<typeof setInterval>;
ngOnInit() {
this.intervalId = setInterval(() => {
this.poll();
}, 3000);
}
ngOnDestroy() {
clearInterval(this.intervalId); // without this the timer keeps running after the component is gone
}
private poll() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode
3. DestroyRef — modern alternative to ngOnDestroy (Angular 16+)
DestroyRef is an injectable token that lets you register a cleanup callback anywhere in the component — right next to the setup code, rather than in a separate ngOnDestroy method. This makes the code easier to follow.
export class PollingComponent implements OnInit {
private destroyRef = inject(DestroyRef);
ngOnInit() {
const intervalId = setInterval(() => {
this.poll();
}, 3000);
this.destroyRef.onDestroy(() => {
clearInterval(intervalId); // cleanup lives next to setup
});
}
private poll() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode
DestroyRef also works well with RxJS via the takeUntilDestroyed operator from @angular/core/rxjs-interop:
import { Component, inject, OnInit } from '@angular/core';
import { DestroyRef } from '@angular/core';
import { interval } from 'rxjs';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({ ... })
export class PollingComponent implements OnInit {
private destroyRef = inject(DestroyRef);
ngOnInit() {
interval(3000)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => this.poll());
}
private poll() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode
The subscription is automatically cancelled when the component is destroyed — no ngOnDestroy needed.
4. Execution order
First render
Order Hook Notes 1constructor
DI only — inputs not yet set
2
ngOnChanges
Only if the component has @Input() properties
3
ngOnInit
Inputs are ready
4
ngDoCheck
5
ngAfterContentInit
Projected content is ready
6
ngAfterContentChecked
7
ngAfterViewInit
Component’s view and child views are ready
8
ngAfterViewChecked
Every subsequent change detection cycle
Order Hook Notes 1ngOnChanges
Only if an @Input() value changed
2
ngDoCheck
3
ngAfterContentChecked
4
ngAfterViewChecked
On destruction
5. Which hooks are used most often?
Hook How common Typical usengOnInit
Very common
Load data, read inputs, subscribe to services
ngOnChanges
Common
React to input changes
ngOnDestroy / DestroyRef
Common
Clean up timers, subscriptions
ngAfterViewInit
Occasional
Access DOM refs, initialize third-party libraries
ngAfterContentInit
Occasional
Access projected content queries
ngDoCheck
Rare
Fine-grained change detection
ngAfterViewChecked
Rare
Post-render DOM reads
ngAfterContentChecked
Rare
Post-check projected content
답글 남기기