[vue 3] ref, reactive의 차이
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()는 반응형 객체를 생성하는 데 사용된다.
이 함수는 객체를 매개변수로 받아 반응형 프록시 객체를 반환함.
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
인프런 짐코딩 강의