dev.syw

라이프사이클 훅과 재사용 가능한 composable 함수 만들기.

라이프사이클과 composable

컴포넌트는 태어나고(생성·마운트), 살아가고(갱신), 사라집니다(언마운트). 이 과정의 특정 시점에 코드를 끼워 넣는 것이 라이프사이클 훅입니다. 그리고 이런 로직을 여러 컴포넌트에서 재사용하고 싶을 때 쓰는 것이 composableuse 로 시작하는 재사용 함수입니다.

학습 목표

  • onMounted·onUnmounted 등 주요 라이프사이클 훅을 안다.
  • 각 훅이 언제 호출되는지 이해한다.
  • 반응형 로직을 composable 함수로 추출한다.
  • composable 작성 규칙(use 접두사, ref 반환)을 익힌다.

라이프사이클 훅

<script setup> 에서 훅을 import 해 콜백을 등록합니다. 가장 많이 쓰는 두 가지는 onMountedonUnmounted 입니다.

<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 에서 정리하세요. 안 그러면 메모리 누수가 생깁니다.

주요 훅 정리

호출 시점용도
onBeforeMountDOM 붙기 직전드물게 사용
onMountedDOM 붙은 직후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 };
}
JavaScript

컴포넌트에서는 호출해서 필요한 것만 꺼내 씁니다.

<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 };
}
JavaScript

이제 어떤 컴포넌트든 const { x, y } = useMouse() 한 줄로 마우스 좌표 기능을 가져옵니다. 리스너 등록·정리까지 composable이 알아서 처리합니다.

💡 TIP — composable은 반드시 ref/reactive 값을 반환하세요. 일반 값을 반환하면 호출 시점의 스냅샷이라 반응성이 사라집니다.

요약

  • 라이프사이클 훅으로 컴포넌트 생애의 특정 시점에 코드를 실행한다.
  • onMounted 는 초기 작업, onUnmounted 는 정리에 쓰며 짝을 맞춘다.
  • composable은 use 로 시작하는 재사용 함수로 반응형 로직을 묶는다.
  • composable은 ref를 반환하고, 필요하면 내부에서 라이프사이클 훅도 쓴다.

연습문제

  1. onMounted 에서 "환영합니다"를 콘솔에 찍고, 1초마다 카운트를 올리는 타이머를 시작해 보세요. onUnmounted 에서 정리도 잊지 마세요.
  2. useCounter composable을 만들고 두 개의 독립적인 카운터를 한 컴포넌트에서 써 보세요.
  3. useMouse 를 사용해 화면에 현재 마우스 좌표를 실시간으로 표시해 보세요.
  4. composable이 일반 값 대신 ref를 반환해야 하는 이유를 설명해 보세요.

힌트useCounter() 를 두 번 호출하면 각각 독립된 count 가 생깁니다. 정리는 onUnmounted(() => clearInterval(timer)).

💡 연습문제 풀이

불러오는 중…

함께 보면 좋은 자료

댓글 0

Vue.js” 강좌에 대한 댓글입니다.

댓글을 작성하려면 로그인이 필요합니다.