라이프사이클 훅과 재사용 가능한 composable 함수 만들기.
라이프사이클과 composable
컴포넌트는 태어나고(생성·마운트), 살아가고(갱신), 사라집니다(언마운트). 이 과정의 특정 시점에 코드를 끼워 넣는 것이 라이프사이클 훅입니다. 그리고 이런 로직을 여러 컴포넌트에서 재사용하고 싶을 때 쓰는 것이 composable — use 로 시작하는 재사용 함수입니다.
학습 목표
onMounted·onUnmounted등 주요 라이프사이클 훅을 안다.- 각 훅이 언제 호출되는지 이해한다.
- 반응형 로직을 composable 함수로 추출한다.
- composable 작성 규칙(
use접두사, ref 반환)을 익힌다.
라이프사이클 훅
<script setup> 에서 훅을 import 해 콜백을 등록합니다. 가장 많이 쓰는 두 가지는 onMounted 와 onUnmounted 입니다.
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const data = ref(null);
let timer = null;
onMounted(() => {
// DOM이 화면에 붙은 직후 — API 호출, 타이머 시작 등
console.log('마운트 완료');
timer = setInterval(() => console.log('tick'), 1000);
});
onUnmounted(() => {
// 컴포넌트가 사라지기 직전 — 정리(cleanup)
clearInterval(timer);
});
</script>
⚠️ 주의 —
onMounted에서 타이머·이벤트 리스너·구독을 시작했다면 반드시onUnmounted에서 정리하세요. 안 그러면 메모리 누수가 생깁니다.
주요 훅 정리
| 훅 | 호출 시점 | 용도 |
|---|---|---|
onBeforeMount | DOM 붙기 직전 | 드물게 사용 |
onMounted | DOM 붙은 직후 | API 호출, DOM 접근, 타이머 |
onUpdated | 반응형 데이터로 DOM 갱신 후 | 갱신 후 처리 |
onUnmounted | 컴포넌트 제거 직후 | 정리(cleanup) |
💡 TIP — 데이터 가져오기는 보통
onMounted에서 합니다.setup(=<script setup>최상단)에서 바로 호출해도 되지만, DOM에 의존하는 작업은onMounted가 안전합니다.
composable — 로직 재사용
같은 반응형 로직을 여러 컴포넌트에서 쓰고 싶다면 함수로 빼냅니다. 이름은 use 로 시작하는 것이 관례입니다.
// composables/useCounter.js
import { ref } from 'vue';
export function useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
const reset = () => (count.value = initial);
return { count, increment, reset };
}
컴포넌트에서는 호출해서 필요한 것만 꺼내 씁니다.
<script setup>
import { useCounter } from './composables/useCounter';
const { count, increment, reset } = useCounter(10);
</script>
<template>
<button @click="increment">{{ count }}</button>
<button @click="reset">리셋</button>
</template>
라이프사이클을 품은 composable
composable 안에서도 라이프사이클 훅을 쓸 수 있습니다. 마우스 위치를 추적하는 예시입니다.
// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue';
export function useMouse() {
const x = ref(0);
const y = ref(0);
const update = (e) => {
x.value = e.clientX;
y.value = e.clientY;
};
onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));
return { x, y };
}
이제 어떤 컴포넌트든 const { x, y } = useMouse() 한 줄로 마우스 좌표 기능을 가져옵니다. 리스너 등록·정리까지 composable이 알아서 처리합니다.
💡 TIP — composable은 반드시 ref/reactive 값을 반환하세요. 일반 값을 반환하면 호출 시점의 스냅샷이라 반응성이 사라집니다.
요약
- 라이프사이클 훅으로 컴포넌트 생애의 특정 시점에 코드를 실행한다.
onMounted는 초기 작업,onUnmounted는 정리에 쓰며 짝을 맞춘다.- composable은
use로 시작하는 재사용 함수로 반응형 로직을 묶는다. - composable은 ref를 반환하고, 필요하면 내부에서 라이프사이클 훅도 쓴다.
연습문제
onMounted에서 "환영합니다"를 콘솔에 찍고, 1초마다 카운트를 올리는 타이머를 시작해 보세요.onUnmounted에서 정리도 잊지 마세요.useCountercomposable을 만들고 두 개의 독립적인 카운터를 한 컴포넌트에서 써 보세요.useMouse를 사용해 화면에 현재 마우스 좌표를 실시간으로 표시해 보세요.- composable이 일반 값 대신 ref를 반환해야 하는 이유를 설명해 보세요.
힌트 —
useCounter()를 두 번 호출하면 각각 독립된count가 생깁니다. 정리는onUnmounted(() => clearInterval(timer)).
💡 연습문제 풀이
불러오는 중…
댓글 0
“Vue.js” 강좌에 대한 댓글입니다.