본문 바로가기
framework_library/vue

🌱 Vue.js 반응형 데이터 이해하기 - reactive와 ref의 차이점 완전정복

by 죄니안죄니 2025. 5. 1.

🌱  Vue.js 반응형 데이터 이해하기 - reactiveref의 차이점 완전정복

Vue 기초 시리즈 > 1️⃣ Vue 기본 개념 이해 > 4️⃣반응형 데이터와 reactive, ref 차이점

  1. Vue의 반응형 시스템이란?
  2. refreactive의 기본 개념
  3. refreactive의 차이점 비교
  4. 실전 예제: refreactive 사용법
  5. 주의사항 및 팁
  6. 마무리 및 다음 글 안내

1. Vue의 반응형 시스템이란?

Vue.js의 반응형 시스템은 데이터의 변경을 자동으로 감지하여 DOM을 업데이트하는 기능입니다. Vue 3에서는 JavaScript의 Proxy를 활용하여 객체의 속성 접근과 변경을 감지합니다. 이를 통해 개발자는 명시적으로 DOM을 조작하지 않아도 데이터 변경에 따라 UI가 자동으로 갱신됩니다.Medium+1SRC Innovations+1


2. refreactive의 기본 개념

ref

  • 모든 타입의 값을 반응형으로 만들 수 있습니다. 
  • 내부적으로 객체 형태로 { value: 실제값 } 구조를 가집니다. 즉, 객체로 감싸지기 때문에 .value를 통해 실제 값을 접근합니다. 단, 템플릿(template) 안에서는 .value 없이 사용 가능합니다. (Vue가 자동 언래핑 해줌)
  • 주로  기본형 데이터 (숫자, 문자열, 불리언 등 원시값 primitive)이나 단일 값을 다룰 때 사용합니다.
import { ref } from 'vue';

const count = ref(0);
console.log(count.value); // 0

count.value++; // 반드시 .value 로 접근해야 반응성이 유지됨

reactive

  • 객체나 배열을 반응형으로 만듭니다.  내부적으로 Proxy를 활용해 속성의 get/set을 감지합니다.
  • 속성에 직접 접근하여 값을 읽고 쓸 수 있습니다.
  • 중첩된 객체도 자동으로 반응형이 됩니다. (중첩된 속성까지 모두 반응형입니다.)
  • state.count++ 형태로 바로 접근하고 사용할 수 있습니다.
import { reactive } from 'vue';

const state = reactive({
  count: 0,
  user: {
    name: '홍길동'
  }
});
console.log(state.count); // 0
console.log(state.user.name); // 홍길동

3. refreactive의 차이점 비교

항목 ref reactive
지원 타입 모든 타입 객체, 배열 등 참조 타입
값 접근 방식 .value 사용 속성에 직접 접근
중첩 객체 반응성 수동으로 처리 필요 자동으로 처리됨
구조 분해 할당 가능 반응성 손실 위험
사용 용도 단일 값, 원시값  객체, 배열, Map, Set 등 복합 자료형, 복합 객체, 상태 관리
상황 DOM 접근이 필요한 경우 (e.g. input 엘리먼트)  

4. 실전 예제: refreactive 사용법

ref 사용 예제

import { ref } from 'vue';

export default {
  setup() {
    const message = ref('안녕하세요');
    const updateMessage = () => {
      message.value = '반갑습니다';
    };
    return { message, updateMessage };
  }
};

reactive 사용 예제

import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      user: {
        name: '홍길동'
      }
    });
    const increment = () => {
      state.count++;
    };
    return { state, increment };
  }
};

5. 둘의 혼합 사용도 가능할까?

 

가능합니다! 예를 들어 reactive 객체 안에 ref를 넣거나, 반대로 ref로 객체를 감싸는 것도 가능합니다. 단, 혼합 시 주의할 점이 있습니다:

// 잘못된 예시
const state = reactive({
  count: ref(0)
});

// state.count.value 해야 하므로 사용이 번거로움
// 추천 방식
const count = ref(0);
const user = reactive({ name: '홍길동' });

5. 주의사항 및 팁

  • ref로 생성된 값은 .value를 통해 접근해야 하며, 템플릿에서는 .value 없이 사용할 수 있습니다.
  • reactive로 생성된 객체를 구조 분해 할당하면 반응성이 손실될 수 있으므로 주의해야 합니다. (구조분해를 해도 ref 자체가 유지되지만, 구조분해하면 reactive는 반응성이 사라져서 toRefs 필요합니다.)
  • reactive는 객체나 배열에 적합하며, ref는 원시값이나 단일 값에 적합합니다. (reactive로 객체를 싸면 Proxy 객체로 전체를 감싸서 속성까지 추적이 되기 때문입니다. 원시값은 객체가 아니라 Proxy로 감쌀 수 없기 때문에 ref로 감싸서 .value로 접근하도록 설계가 된 것입니다.)
  • 복잡한 상태 관리를 위해 reactiveref를 함께 사용할 수 있습니다.

🔎 예시로 설명해볼게요

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  name: '홍길동'
});

// ❌ 구조 분해 할당
const { count, name } = state;

console.log(count); // 0

위처럼 const { count, name } = state로 구조 분해하면 count, name은 단순한 값 복사일 뿐, reactive()의 추적 시스템과는 끊어지게 됩니다.

즉, 이 변수들은 Vue가 감시할 수 없는 값이 되고, count나 name이 변경돼도 화면에 반영되지 않습니다.

✅ 반응성 유지 방법

구조 분해를 하지 않고 state.count처럼 원본 객체를 직접 사용

console.log(state.count); // 이건 반응형 유지됨

 

toRefs()를 사용해서 반응형을 유지한 채 구조 분해하기:

import { reactive, toRefs } from 'vue';

const state = reactive({
  count: 0,
  name: '홍길동'
});

const { count, name } = toRefs(state); // 이건 반응성 유지됨

count.value++; // 반응형 유지됨

🧠 정리

방식 반응성 유지 여부 설명
const { count } = state 구조 분해로 단순 값만 가져오므로 반응성 X
const { count } = toRefs(state) ref로 변환되어 반응성 유지됨
state.count 원본 reactive 객체 사용
 

6. 마무리 및 다음 글 안내

이제 Vue의 반응형 시스템과 ref, reactive의 차이점을 이해하셨습니다. 다음 글에서는 컴포넌트 기반 개발에 대해 자세히 알아보겠습니다.

👉 다음 글: 컴포넌트 선언과 등록 방식 (전역, 지역)

댓글