반응형
출처 : https://vuejs.org/guide/extras/reactivity-in-depth.html
아래와 같은 코드가 실행된다 가정하자
import { ref, watchEffect } from 'vue'
const A0 = ref(0)
const A1 = ref(1)
const A2 = ref()
watchEffect(() => {
// tracks A0 and A1
A2.value = A0.value + A1.value
})
// triggers the effect
A0.value = 2
1. 이펙트(ex: watchEffect,computed 내부 함수) 함수가 전역 변수에 할당되며 파라미터로 받은 업데이트 함수를 실행함
- 초기에 A2 값을 만들기 위함
// 전역 변수
let activeEffect;
function watchEffect(update) {
const effect = () => {
activeEffect = effect
update()
activeEffect = null
}
effect()
}
2. 업데이트 함수 내에서 reactive한 객체에 접근하여 프록시 트랩 get 호출
- return target[key]를 통해 값을 리턴함
- 그 전에 track 함수를 실행
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
track(target, key)
return target[key]
},
set(target, key, value) {
target[key] = value
trigger(target, key)
}
})
}
function ref(value) {
const refObject = {
get value() {
track(refObject, 'value')
return value
},
set value(newValue) {
value = newValue
trigger(refObject, 'value')
}
}
return refObject
}
3. 프록시 트랩 내의 track함수는 1에서 전역 변수에 할당된 이펙트를 해당 속성의 구독자 목록에 추가함
- 예를 들어 A2= A1+A0이면, update 함수는 ()=>A2.value=A1.value+A0.value임
- 해당 update 함수를 내부에서 호출하는 effect 함수는 각각 A1속성, A0속성의 구독자 목록에 추가됨.
- getSubscribersForProperty는 WeakMap<target, Map<key, Set<effect>>>에서 객체와 키를 통해 이펙트 목록를 가져오는 함수라 생각 가능
// This will be set right before an effect is about
// to be run. We'll deal with this later.
let activeEffect
function track(target, key) {
if (activeEffect) {
const effects = getSubscribersForProperty(target, key)
effects.add(activeEffect)
}
}
4. 반응형 객체의 특정 속성값이 변경되면, 해당 속성값에 대한 구독자 함수를 전부 호출해줌
- 2의 set 프록시 트랩
- 예를 들어 A2= A1+A0이면
- A1이 변경되면 effect 호출하여 A2 갱신
- A0이 변경되면 effect호출하여 A2 갱신
function trigger(target, key) {
const effects = getSubscribersForProperty(target, key)
effects.forEach((effect) => effect())
}
5. 해당 객체에 바인딩 된 뷰가 업데이트됨
- 뷰의 patch, update 라이프사이클
비고
프록시를 통한 반응성을 얻으려면, 프록시 객체를 통해 객체 프로퍼티에 직접 접근 가능해야함.
- 로컬 변수에 할당하거나 구조분해 할 경우, primitive 값의 경우는 의존성 추적이 끊길 수 있음. (새 이름표에 새 값 할당)
- 당연히 원본과 동등 비교 === 불가
반응형
'FrontEnd' 카테고리의 다른 글
크롬 개발자 도구의 QueryObjects 객체로 Javascript 메모리 누수 잡기 (0) | 2022.11.19 |
---|---|
프론트엔드 성능 최적화 가이드 스터디 4장 (0) | 2022.11.19 |
프론트엔드 성능 최적화 가이드 3장 스터디 (0) | 2022.11.17 |
프론트엔드 성능 최적화 가이드 2장 스터디 (0) | 2022.11.15 |
프론트엔드 성능 최적화 가이드 1장 스터디 (0) | 2022.11.15 |