Vue.js 라이프사이클: Composition API 훅으로 보는 컴포넌트의 일생

한눈에 보기

Vue 컴포넌트가 생성, 마운트, 갱신, 소멸하는 라이프사이클 전 과정을 다룬다. Composition API 훅의 시점별 역할과 Options API 대응 관계, 데이터 요청과 자원 정리를 배치하는 올바른 시점을 정리한다.

최종 업데이트 2026.09.17

Vue.js(뷰) 라이프사이클은 컴포넌트가 생성되어 DOM에 연결되고, 데이터 변화에 따라 갱신되다가, 화면에서 제거되기까지의 전체 과정을 뜻한다. Vue 3의 Composition API(컴포지션 API)는 이 과정의 각 시점에 onMounted, onUpdated, onUnmounted 같은 훅 함수를 등록해 부수 작업을 실행할 수 있게 한다. 라이프사이클을 정확히 이해하면 데이터 요청, DOM 접근, 자원 정리를 각각 올바른 시점에 배치할 수 있다.

라이프사이클의 네 단계

컴포넌트의 일생은 크게 생성(creation), 마운트(mount), 갱신(update), 소멸(unmount)의 네 단계로 나뉜다. 생성 단계에서는 컴포넌트 인스턴스가 만들어지고 반응형 상태가 준비된다. 마운트 단계에서는 템플릿이 렌더 함수로 실행되어 가상 DOM(virtual DOM)이 만들어지고 실제 DOM에 삽입된다. 갱신 단계는 반응형 의존성이 변할 때마다 반복되며, 새 가상 DOM과 이전 결과를 비교해 달라진 부분만 실제 DOM에 반영한다. 소멸 단계에서는 컴포넌트가 DOM에서 제거되면서 감시자(watcher), 이벤트 리스너, 자식 컴포넌트가 함께 정리된다.

Composition API의 라이프사이클 훅

Composition API에서는 script setup 블록 또는 setup 함수의 실행 자체가 생성 단계다. 그래서 Options API(옵션스 API)의 beforeCreate와 created에 해당하는 훅은 따로 존재하지 않고, 그 자리에서 하던 초기화 코드는 setup 본문에 그대로 쓰면 된다. 이후 시점은 다음 함수들로 등록한다.

  • onBeforeMount, onMounted: DOM 삽입 직전과 직후에 호출된다. DOM 접근이 필요한 작업은 onMounted 이후에만 안전하다.
  • onBeforeUpdate, onUpdated: 반응형 변화로 인한 재렌더링 직전과 직후에 호출된다.
  • onBeforeUnmount, onUnmounted: 컴포넌트 제거 직전과 직후에 호출되며 자원 정리를 담당한다.
  • onActivated, onDeactivated: keep-alive로 캐시된 컴포넌트가 화면에 나타나고 사라질 때 호출된다.
  • onErrorCaptured: 자식 컴포넌트에서 전파된 오류를 가로챌 때 쓴다.

Options API와의 대응 관계

Vue 2 시절부터 쓰이던 Options API의 라이프사이클 옵션은 Composition API 훅과 다음처럼 대응한다. Vue 3에서 beforeDestroy와 destroyed가 beforeUnmount와 unmounted로 이름이 바뀐 점도 함께 기억해 두면 좋다.

Options APIComposition API시점
beforeCreate, createdsetup 본문인스턴스 생성과 상태 초기화
beforeMountonBeforeMountDOM 삽입 직전
mountedonMountedDOM 삽입 직후
beforeUpdateonBeforeUpdate재렌더링 직전
updatedonUpdated재렌더링 직후
beforeUnmountonBeforeUnmount제거 직전
unmountedonUnmounted제거 직후

단계별 활용 예시

가장 흔한 조합은 onMounted에서 데이터를 불러오고 onUnmounted에서 타이머나 구독을 해제하는 패턴이다.

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const items = ref([]);
let timer = null;

async function refresh() {
  const res = await fetch('/api/items');
  items.value = await res.json();
}

onMounted(() => {
  refresh();
  timer = setInterval(refresh, 5000);
});

onUnmounted(() => {
  clearInterval(timer);
});
</script>

타이머, 웹소켓, 전역 이벤트 리스너처럼 컴포넌트 바깥에 남는 자원은 반드시 onUnmounted에서 해제해야 한다. 정리를 빠뜨리면 컴포넌트가 사라진 뒤에도 콜백이 계속 실행되어 메모리 누수와 예측하기 어려운 오류로 이어진다.

주의할 점

  • onUpdated 안에서 반응형 상태를 변경하면 다시 갱신이 일어나 무한 루프에 빠질 수 있다. 갱신 후 DOM을 읽는 용도로만 쓰는 것이 안전하다.
  • 서버 사이드 렌더링(Server-Side Rendering) 환경에서는 서버에서 setup만 실행되고 onMounted 이후의 훅은 브라우저에서만 호출된다. window 같은 브라우저 전용 API 접근은 onMounted 안에 두어야 한다.
  • keep-alive로 캐시된 컴포넌트는 화면에서 사라져도 언마운트되지 않으므로, 표시 여부에 따른 작업은 onActivated와 onDeactivated로 처리한다.
  • 라이프사이클 훅은 setup의 동기 실행 중에 등록해야 한다. await 뒤에 등록하면 현재 컴포넌트 인스턴스와 연결되지 않아 경고와 함께 무시된다.

면접에서 이렇게 물어본다

  • Composition API에 beforeCreate와 created에 해당하는 훅이 없는 이유는 무엇인가.
  • 데이터 요청을 setup 본문과 onMounted 중 어디에서 하는지, 두 위치의 차이는 무엇인지 설명해 보라.
  • onUnmounted에서 정리해야 하는 자원의 예를 들고, 정리하지 않으면 어떤 문제가 생기는가.
  • keep-alive로 감싼 컴포넌트의 라이프사이클은 일반 컴포넌트와 어떻게 다른가.
  • SSR 환경에서 호출되지 않는 라이프사이클 훅은 무엇이며 왜 그런가.
React / Vue 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기