Vue

[vue 3] ref, reactive의 차이

머지?는 병합입니다 2023. 3. 26. 16:16

Vue 2에서 많이 사용했던 기존 optional api의 data( )  안에 정의했던 내용을

composition api 형태로 사용시 setup 안에서 정의해주는 형태로 변경되었다. 

// optional api 
export default {
  data() {
    return {
      count: 1
    }
  },
}

 

이때 ref() 및 reactive()는 반응형 데이터 객체를 만드는 데 사용할 수 있는 두 가지 함수이다.

 

1. ref( ) 

 

ref()는 값에 대한 반응형 참조를 만드는 데 사용된다. 

primitive type  , reference type 둘 다 사용 가능함.

 

value 프로퍼티는 참조 값을 가져오거나 설정하는 데 사용할 수 있다.

( 쉽게 이야기 해서 ref 로 정해진 변수의 값에 접근할 때는 변수명 . value 로 해야 접근이 된다)

 

ref() 사용 예시:

import { ref } from 'vue'

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

count.value++
console.log(count.value) // 1

DB에서 잊지말자 commit; 이 있다면 vue3 에서는 잊지말자 .value 이다...

(전 분명히 말씀드림..... 까먹고 .value 안 써서 빨간 로그창 보시는 분 꼭 한분씩 계시더라... 물론 내 얘기...)


2. reactive()

 

reactive()는 반응형 객체를 생성하는 데 사용된다. 

이 함수는 객체를 매개변수로 받아 반응형 프록시 객체를 반환함. 

  1. 객체, 배열 그리고 Map이나 Set과 같은 컬렉션 유형에만 작동하며,  
    string, number 또는 boolean과 같은 primitive type 에 사용할 수 없다.

 

reactive() 사용 예시:

import { reactive } from 'vue'

const state = reactive({
  count: 0,
  message: 'Hello World'
})
console.log(state.count) // 0

state.count++
console.log(state.count) // 1

3. ref( )  와 reactive() 의 차이

ref ( ) 로 객체를 다루게 되면 슬슬 헷갈리게 되는데 간단하게 정리해보자면..

 

ref ( ):  value 프로퍼티에 새로운  proxy 객체를 할당함으로써 수행. (관심사는 value 그 자체.)

reactive( ):  값을 하나하나 접근해서 변경은 가능. (관심사는 object 그 자체.)

                  하지만 객체 구조를 망가트리거나 완전 새로운 객체로 통으로 교체하는 것은 불가능.

                  왜냐하면 기존 객체를 감싸는 Proxy 객체를 생성하여 변경 사항을 감지하는데,

                  우리가 객체를 바꾸면 이 Proxy 객체 바꾸는 게 된다.

                  그럼 Proxy 객체와 원래 객체가 달라지므로 일관성이 끊어져 코드는 고장나게 된다.

const state = ref({
  isVisible: true,
  name: 'Markus',
});

// 1. `ref( )` 객체는 .value 를 해야 속성에 접근이 되지만
//   `reactive()` 는 state.isVisible = false 
//    이렇게 value 가 없어서 편함...

state.value.isVisible = false;


// 2. 하지만 `reactive()` 가 마냥 편한 건 아닌게..
// 아래처럼 객체를 통채로 바꿔 끼우는 게 안됨..

state.value = {
  isVisible: false,
  name: 'John',
};

 

 

반응형 객체의 다수의 속성을 사용하길 원할 때 구조분해 할당을 이용하는 게 보통이지만,

value로 접근하는 ref 와는 달리 

reactive에서는 객체 자체를 새로 갈아끼울 순 없어서 반응성이 끊어지게 되므로toRefs, toRef 를 사용해야 한다.

import { reactive } from 'vue'

const book = reactive({
  author: 'God',
  year: 'unkmown',
  title: 'Bible',
  description: '인류 역사상 최고의 베스트 셀러',
  price: '싯가'
})

let { author, title } = book // X. 반응성 끊어짐
let { author, title } = toRefs(book) //O. 반응성 연동됨.

 

 

 

또한 전개구문도 못씀....

 

//api.js
const posts = [
  { id: 1, title: '제목1', content: '내용1', createdAt: '2020-01-01' },
  { id: 2, title: '제목2', content: '내용2', createdAt: '2020-02-02' },
  { id: 3, title: '제목3', content: '내용3', createdAt: '2020-03-03' },
  { id: 4, title: '제목4', content: '내용4', createdAt: '2020-04-04' },
  { id: 5, title: '제목5', content: '내용5', createdAt: '2020-05-05' },
];

export function getPostById(id) {
  const numberId = parseInt(id);
  return posts.find(item => item.id === numberId);
}


// something.vue

//ref
const form = ref({});
const fetchPost = () => {
  const data = getPostById(id);
  form.value = {...data};		// ref 는 spread 가 되지만...
};

//reactive
const form = reactive({});
const fetchPost = () => {
  const data = getPostById(id);
  form.title = data.title;		//한땀, 한땀 바꿔줘야함....
  form.content = data.contnent;
};

 

참고:  https://markus.oberlehner.net/blog/vue-3-composition-api-ref-vs-reactive/

 

Vue 3 Composition API: ref() vs. reactive()

Learn when to use ref() and when to use reactive() and why you should consider always using ref() instead of reactive().

markus.oberlehner.net

인프런 짐코딩 강의