Vue reactivity
Vue.js는 state-driven UI 모델을 표방하지만, "state를 바꾸면 화면이 알아서 바뀐다"는 문장 자체는 메커니즘을 설명하지 않는다. Reactivity가 바로 그 메커니즘이다 — developer는 state를 바꾸고, Vue는 그 state에 의존하는 rendering 결과를 갱신한다. 이는 event handler마다 DOM node를 직접 찾아 수정하는 방식과 대비되는, state change와 UI update 사이의 추적 관계다. ref vs reactive는 이 reactivity를 사용하는 API 선택 문제이고, 이 페이지는 그 밑에 있는 감지·추적 메커니즘 자체를 다룬다.
감지: state가 바뀌면 무슨 일이 일어나는가
- Vue는 state 변화를 감지하고 그 state를 쓰는 DOM을 자동으로 갱신한다.[1]
- 이 감지는 두 API로 진입한다.[2]
ref(): primitive value와 object를 reactive reference로 감싼다.reactive(): object, array, collection처럼 이미 참조 가능한 값에 적합한 reactive state를 만든다.- Template 안에서는 ref가 자동 unwrap되지만, script logic에서는
.value로 접근해야 한다.
import { ref, reactive } from "vue";
const count = ref(0);
count.value++;
const user = reactive({ nickname: "hissam" });
user.nickname = "vue-user";
추적: Proxy와 getter/setter
- Vue 3에서
reactive()는 Proxy로 object access를 가로채 dependency tracking과 trigger를 수행하고,ref()는.value의 getter/setter로 같은 역할을 한다.[3] - 이 Proxy 기반 추적이 있기 때문에, state 변화가 자동으로 rendering 결과에 반영된다는 위 감지 절이 실제로 성립한다.
flowchart LR Event["event/API/user input"] --> State["reactive state changes"] State --> Tracking["Vue tracks dependencies"] Tracking --> Render["component render updates"] Render --> DOM["DOM patch"]
추적이 끊기는 두 지점
- Destructuring/local assignment: reactive object의 property를 local variable로 destructuring하거나 assign하면, 그 local variable에 대한 접근은 더 이상 Proxy trap을 통과하지 않는다.[4]
- object property 자체를 바꾸는 mutation은 계속 reactive다.
- local binding만 바꾸는 것은 source state를 갱신하지 않는다.
- Render와 DOM patch 사이의 시차: component render update는 state mutation 직후의 동기 DOM mutation을 뜻하지 않는다. Vue는 update를 batch 처리할 수 있으므로, mutation 직후 DOM을 즉시 읽어야 한다면 이 batching 경계를 고려해야 한다.[5]
절충점
- 장점: 수동 DOM update를 줄이고 state와 UI의 일관성을 높인다.
- 장점: template은 state에서 UI를 선언하는 방식으로 읽힌다.
- 비용:
ref()의.value, object reassignment, destructuring 같은 API 경계를 이해해야 한다.
흔한 실패 모드
- State를 바꾸지 않고 DOM을 직접 mutate하는 경우.
- Primitive value에
reactive()를 쓰려는 경우. - Script logic에서 ref의
.value를 잊는 경우. ref()와reactive()를 별개 철학처럼 과장해 전체 reactivity model을 놓치는 경우.
경계
- Reactivity는 state 관리의 전부가 아니다. Data fetching, global store, server cache, routing state는 별도 설계가 필요할 수 있다.
ref()와reactive()의 차이는 reactivity model 자체의 차이라기보다 state shape와 access style에 따른 API 선택이다.- Vue component rendering과 JavaScript state 위에서 동작하며, form state·modal state·list rendering·computed rendering처럼 state가 자주 바뀌고 화면에 바로 반영돼야 하는 곳에서 특히 쓰인다.
관련
- Vue.js: reactivity는 Vue의 state-driven UI 모델을 구현한다.
- ref vs reactive: reactive state API 선택 기준을 설명한다.
- Vue app instance: Vue runtime이 mount된 뒤 component state 변화가 화면에 반영된다.
- JavaScript Language Model:
reactive()가 기대는 Proxy trap과 Reflect 위임이 언어 차원에서 무엇인지 설명하므로, 이 page의 Proxy 추적 절을 JavaScript 쪽에서 받친다고 볼 수 있다.
출처
테스트 질문
- Vue reactivity는 Vue 전체 모델에서 어떤 역할을 하는가?
ref()와reactive()는 reactivity와 어떤 위계 관계인가?- Reactivity를 DOM update helper로만 이해하면 무엇을 놓치는가?
01-1.Vuejs-intro.pdf — "Vue가 state 변화를 감지하고 DOM을 자동으로 갱신한다" ↩︎
01-1.Vuejs-intro.pdf — ref()/reactive() 정의와 template unwrap 규칙 ↩︎
vue-reactivity-in-depth.md — "In Vue 3, Proxies are used for reactive objects and getter / setters are used for refs." ↩︎
vue-reactivity-in-depth.md — "When you assign or destructure a reactive object's property to a local variable, accessing or assigning to that variable is non-reactive..." ↩︎
출처 매핑 미확인 — next-tick/batching 주장이 두 인용 소스 어디에서도 확인되지 않는다(
01-1.Vuejs-intro.pdf는 그렙 불가,vue-reactivity-in-depth.md는batch/nextTick검색 결과 없음). Vue 공식 문서의 lifecycle 또는nextTick문서를 새로 읽어 확인할 것. ↩︎