Angular의 ViewChild와 라이프사이클 훅, 정말 코드 스멜인가?
2025-04-19 04:12:36ViewChild와 라이프사이클 훅: 오해와 진실
Angular를 사용할 때 ViewChild와 라이프사이클 훅이 코드 스멜이라는 의견이 종종 나옵니다. 그러나 이는 도구의 부적절한 사용을 코드 스멜로 오해하는 경우입니다. ViewChild와 ngAfterViewInit 등은 올바른 상황에서 강력한 도구로 활용될 수 있습니다.
ViewChild란 무엇인가?
ViewChild는 Angular에서 제공하는 데코레이터로, 부모 컴포넌트가 자식 컴포넌트의 인스턴스, 디렉티브 또는 DOM 요소에 접근할 수 있게 합니다. 이 도구는 잘못 사용하면 디자인 문제를 일으킬 수 있으므로, 의도에 맞게 사용하는 것이 중요합니다.
ViewChild가 문제가 될 수 있는 경우
부모-자식 간의 지나친 통신
ViewChild를 자주 사용하여 자식 컴포넌트의 메서드를 호출하거나 속성을 설정하면 강한 결합이 발생합니다. 대신, @Input()으로 데이터를 전달하고 @Output()과 EventEmitter를 사용하여 부모에게 알리는 방법을 고려하세요.
직접적인 DOM 조작
ElementRef를 가져와 DOM을 조작하기 위해 ViewChild를 사용하는 것은 Angular의 추상화를 무너뜨립니다. 프로퍼티 바인딩, 어트리뷰트 바인딩, 또는 커스텀 디렉티브 같은 Angular의 방법을 사용하는 것이 좋습니다.
ngAfterViewInit vs. ViewChild의 Setter
ViewChild setter는 ngAfterViewInit을 대체할 수 없습니다. Setter는 특정 참조가 가능할 때 실행되지만, ngAfterViewInit은 전체 뷰 초기화 이후에 실행됩니다.
ViewChild와 ngAfterViewInit의 적절한 사용 사례
외부 라이브러리 통합
외부 라이브러리, 예를 들어 Chart.js나 Swiper를 사용하기 위해서는 직접적인 DOM 참조가 필요합니다. 이 경우 ViewChild와 ngAfterViewInit을 활용할 수 있습니다.
import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import Chart from 'chart.js/auto'; // 예시: Chart.js
@Component({
selector: 'app-chart',
template: '<canvas #myCanvas></canvas>',
})
export class ChartComponent implements AfterViewInit {
@ViewChild('myCanvas') myCanvas!: ElementRef<HTMLCanvasElement>;
chart: any;
ngAfterViewInit(): void {
const context = this.myCanvas.nativeElement.getContext('2d');
if (context) {
this.chart = new Chart(context, {
type: 'bar',
data: { /* 데이터 */ },
options: { /* 옵션 */ }
});
} else {
console.error('Could not get the 2D context from the canvas.');
}
}
}
렌더 후 UI 로직
툴팁의 위치 조정이나 레이아웃 변경, 뷰포트 가시성 검사 등의 작업에는 렌더 후 DOM 접근이 필요합니다. ngAfterViewInit을 통해 적절한 타이밍에 실행할 수 있습니다.
여러 자식 요소에 영향을 미치는 디렉티브
ngAfterViewInit이나 ngAfterContentInit과 함께 @ViewChildren 또는 @ContentChildren을 사용하는 것이 적합할 수 있습니다.
동적 크기 계산 및 위치 조정
마지막으로 렌더된 뷰가 필요할 때가 있습니다. 요소의 크기 및 위치에 기반하여 작업을 수행할 때 ngAfterViewInit을 활용하세요.
결론
ViewChild와 ngAfterViewInit의 개념과 활용은 Angular 개발에 있어 중요한 부분입니다. 잘못된 사용이 아니라, 필요에 맞추어 올바르게 사용하는 것이 중요합니다. 추가적인 자료는 아래 링크를 참고해주세요.