- 데이터 타입:
- ref: 단일 값이나 원시 타입
- reactive: 객체, 배열 등 복합 데이터 구조
- 데이터 사용법:
- ref: .value를 통해 접근
- reactive: 일반 객체처럼 속성에 직접 접근
ref와 reactive 모두 반응형 데이터를 다룰 때 사용하지만, 다루는 데이터 타입이 다르다는 특징이 있다. 그러나 reactive는 ref와 달리 데이터의 값이 수정되거나 추가될 때 등 반응성을 잃는다는 점에서 주의해야 한다.
Vue의 반응형 시스템은 reactive 객체 생성 시점에 존재하는 속성들만 추적하기 때문에, 새로 추가된 속성은 반응형으로 처리되지 않는다.
1. 속성 추가
const state = reactive({ count: 0 });
state.newProperty = 5;
console.log(state.newProperty); // 5
// Vue는 더이상 newProperty를 반응형으로 추적하지 않는다.
2. 데이터 수정
let state = reactive({ count: 0 });
state = { count: 1 };
이 경우 state 자체를 다른 객체로 할당했기 때문에 반응형으로 추적하지 않는다.
3. 배열의 인덱스 값 또는 길이를 수정하는 경우
const state = reactive([1, 2, 3]);
state[1] = 10;
해결방법
reactive를 사용한 반응형 객체가 반응성을 잃었을 때, 아래와 같은 방법을 사용해 반응성을 유지할 수 있다.
- Vue.set() 또는 Object.assign(): 객체에 새로운 속성을 추가할 때 Vue.set() (Vue 2의 경우) 또는 Object.assign() 등을 사용.
- toRefs() : 개별 속성을 반응형으로 만들어주는 toRefs() 사용.
- 배열 메서드 주의: 배열은 push, pop, splice 등 Vue에서 감지할 수 있는 메서드 사용.
Object.assign()
const initState = {
isEmpty: false,
name: "",
phone: "",
};
const formState = reactive({ ...initState });
const reset = () => {
Object.assign(formState, initState);
};
const formState = reactive({
isEmpty: false,
name: "",
phone: "",
});
const getData = (params) => {
Object.assign(formState, params);
refetch();
};
toRefs()
const state = reactive({
isEmpty: false,
name: "",
phone: "",
});
const { isEmpty, name, phone } = toRefs(state);
ref 또는 reactive 중 한 가지만 사용하길 권장하는 이유
1. 코드 일관성
- ref의 경우 value를 통해 데이터에 접근할 수 있기 때문에 혼란을 야기할 수 있고, 코드의 일관성이 떨어진다.
2. 가독성과 유지보수성
- 코드 스타일이 일관되지 않아 유지보수가 어려울 수 있다.
- 코드 작성 시 어떤 상황에 무엇을 사용할지 매번 고민하게 되기 때문에 개발 효율성이 떨어질 수 있다.
3. 타입스크립트 호환성
- TypeScript를 사용할 때는 reactive보다 ref가 더 명확한 타입 정의를 제공하는 경우가 있다. 혼합 사용 시 타입 정의가 복잡해지거나 의도하지 않은 타입 오류가 발생할 수 있다.
- 한 가지 방식을 일관되게 사용하면 타입 시스템과의 호환성을 더 쉽게 유지할 수 있다.
4. 사용성
ref는 원시 값이나 단일 값의 반응성을 다루는 데 적합하고, reactive는 객체나 배열 같은 복합 데이터 구조에 적합하기 때문에 한 가지 방식으로 통일하게 되면 "어떤 데이터에 어떤 함수를 쓸지"에 대한 모호함이 줄어들게 된다.
댓글