[Angular] 생명주기(Lifecycle) 와 훅(Hook) 메서드 이해

Angular는 개발자가 동적이고 반응성이 뛰어난 웹 애플리케이션을 구축할 수 있는 강력한 프레임워크입니다. Angular의 주요 기능 중 하나는 각 컴포넌트가 고유한 생명주기(Lifecycle)를 갖는 컴포넌트 기반 아키텍처입니다. 이러한 생명주기를 이해하는 것은 효율적이고 성능이 뛰어난 애플리케이션을 구축하는 데 중요합니다.

이 글에서는 Angular에서 사용할 수 있는 다양한 생명주기 훅(Hook) 메서드와 차이점, 그리고 이를 사용하는 모범 사례를 살펴보겠습니다.

생명주기 훅 메서드이란 무엇입니까?

Angular 생명주기 훅 메서드는 컴포넌트 생명 주기 중 특정 지점에서 호출되는 메서드입니다. 이러한 훅 메서드를 사용하면 컴포넌트(component)의 초기화, 생성 및 삭제와 같은 특정 시점에 작업을 수행할 수 있습니다.

Angular에는 8개의 생명주기 메서드가 있습니다.

  1. ngOnChanges(): 컴포넌트의 입력 속성 중 하나 이상이 변경될 때 호출됩니다.
  2. ngOnInit(): 컴포넌트의 입력 속성이 초기화된 후 컴포넌트가 표시되기 전에 호출됩니다.
  3. ngDoCheck(): 모든 변경 감지 주기 동안 호출되므로 변경 사항을 감지하고 그에 따라 조치를 취할 수 있습니다.
  4. ngAfterContentInit(): 컴포넌트의 콘텐츠가 해당 뷰에 투영된 후에 호출됩니다.
  5. ngAfterContentChecked(): 컴포넌트의 콘텐츠를 확인할 때마다 호출됩니다.
  6. ngAfterViewInit(): 컴포넌트의 뷰가 초기화된 후에 호출됩니다.
  7. ngAfterViewChecked(): 컴포넌트 뷰를 확인할 때마다 호출됩니다.
  8. ngOnDestroy(): 컴포넌트가 파괴되기 직전에 호출됩니다.

이러한 각 메서드는 컴포넌트 생명 주기에서 특정 목적을 수행하므로 특정 시점에 작업을 수행할 수 있습니다.

차이점

이러한 생명 주기 훅 메서드 간의 몇 가지 차이점을 자세히 살펴보겠습니다.

ngOnChanges() vs ngOnInit()

ngOnChanges() 메서드는 컴포넌트의 입력 속성 중 하나 이상이 변경될 때 호출됩니다. 컴포넌트 입력 데이터의 변경 사항에 따라 작업을 수행해야 할 때 유용합니다.

반면에 ngOnInit()은 컴포넌트의 입력 속성이 초기화된 후 컴포넌트가 표시되기 전에 호출됩니다. 초기화 작업을 수행하거나 서비스에서 데이터를 검색해야 할 때 유용합니다.

ngDoCheck() vs ngAfterContentChecked()

ngDoCheck() 메서드는 모든 변경 감지 주기 동안 호출되므로 변경 사항을 감지하고 그에 따라 조치를 취할 수 있습니다. 사용자 정의(Custom) 변경 감지를 수행해야 하거나 사용자 정의 변경 감지 전략을 구현해야 할 때 유용합니다.

반면에 ngAfterContentChecked()는 컴포넌트의 콘텐츠를 확인할 때마다 호출됩니다. 뷰 업데이트와 같이 컴포넌트 콘텐츠의 변경 사항에 따라 작업을 수행해야 할 때 유용합니다.

ngAfterViewInit() vs ngAfterViewChecked()

ngAfterViewInit() 메서드는 컴포넌트의 뷰가 초기화된 후에 호출됩니다. 컴포넌트의 뷰에 액세스해야 하는 초기화 작업을 수행해야 할 때 유용합니다.

반면에 ngAfterViewChecked()는 컴포넌트 뷰를 확인할 때마다 호출됩니다. 뷰 업데이트와 같이 컴포넌트 뷰의 변경 사항에 따라 작업을 수행해야 할 때 유용합니다.

모범사례

  1. ngOnInit() 메서드에서 복잡한 논리를 피하십시오. 컴포넌트 속성을 초기화하고 기본 설정 작업을 수행하는 데에만 사용해야 합니다. 더 복잡한 로직을 수행해야 하는 경우 별도의 서비스나 기능으로 이동하는 것을 고려해 보세요.

  2. 반응형 입력 처리를 위해 ngOnChanges()를 사용하세요. 입력 속성에 대한 변경 사항을 처리하기 위해 특별히 설계되었습니다. 이를 사용하여 컴포넌트 상태를 업데이트하거나 입력 값의 변경 사항에 따라 다른 작업을 수행합니다.

  3. DOM 조작을 위해 ngAfterViewInit() 메서드를 사용하세요. 뷰가 초기화된 후에 호출되며 DOM을 조작하기에 적합한 위치입니다. 이를 사용하여 이벤트 리스너를 설정하고 요소를 추가 또는 제거하거나 기타 DOM 관련 작업을 수행합니다.

  4. 정리를 위해 ngOnDestroy()를 사용하지 마세요. 컴포넌트 리소스를 정리하도록 설계되었지만 항상 신뢰할 수 있는 것은 아닙니다. 대신 서비스를 사용하거나 컴포넌트의 ngOnDestroy 이벤트를 구독하여 정리 작업을 수행하는 것을 고려해 보세요.

다음은 ngOnDestroy()에만 의존하는 대신 서비스를 사용하여 정리 작업을 수행하는 방법에 대한 예입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Injectable } from '@angular/core';
import { Subscription } from 'rxjs';

@Injectable({
providedIn: 'root',
})
export class CleanupService {
private subscriptions: Subscription[] = [];

addSubscription(subscription: Subscription): void {
this.subscriptions.push(subscription);
}

cleanup(): void {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
}
}

그런 다음 컴포넌트에 CleanupService를 삽입하고 이를 사용하여 Subscription(구독)을 관리할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { Component, OnInit, OnDestroy } from '@angular/core';
import { interval, Subscription } from 'rxjs';
import { CleanupService } from './cleanup.service';

@Component({
selector: 'app-example',
template: '<p>{{ message }}</p>',
})
export class ExampleComponent implements OnInit, OnDestroy {
message: string;
private subscription: Subscription;

constructor(private cleanupService: CleanupService) {}

ngOnInit(): void {
this.subscription = interval(1000).subscribe(() => {
this.message = 'Hello, world!';
});
this.cleanupService.addSubscription(this.subscription);
}

ngOnDestroy(): void {
// Don't use ngOnDestroy for cleanup!
// Instead, use the CleanupService to perform cleanup tasks.
this.cleanupService.cleanup();
}
}

위의 예에서는 CleanupService를 사용하여 컴포넌트의 Subscription을 관리합니다. addSubscription() 메서드는 Subscription 배열에 추가하고 cleanup() 메서드는 배열의 각 Subscription에 대해 unsubscribe()를 호출합니다. 그런 다음 컴포넌트의 ngOnDestroy() 메서드에서 ngOnDestroy()에만 의존하는 대신 CleanupService를 사용하여 정리 작업을 수행합니다. 이렇게 하면 어떤 이유로 ngOnDestroy()가 호출되지 않더라도 컴포넌트의 리소스가 적절하게 정리됩니다.

이러한 사례를 따르면 일반적인 함정을 피하고 성능을 향상시키면서 컴포넌트가 현재 작업에 적합한 생명 주기를 사용하고 있는지 확인할 수 있습니다.

결론적으로, 고품질의 고성능 Angular 애플리케이션을 구축하려면 Angular 생명 주기를 이해하는 것이 중요합니다. 각 훅 메서드 간의 차이점을 살펴보고 사례를 따르면 Angular 프레임워크를 최대한 활용하고 강력하고 유지 관리가 가능한 애플리케이션을 구축할 수 있습니다.

Share