반응형 상태가 변경되었을때, 감지하여 다른작업(api call 등...)을 수행해야 하는 경우가 있다. 이때 Composition API의 Watch, WatchEffect를 사용하면 된다.
watch(message, (newValue, oldValue) => {
첫번째 매개변수 : 어떤 반응형 데이터의 변경을 감지할지 적는다.
두번째 매개변수 : 콜백함수 (첫번째: 변경된 값, 두번째: 변경되기 이전의 값)
});
watch의 첫번째 매개변수는 다양한 타입이 들어올 수 있다. ref, reactive, computed, getter함수, array 등
// 1. single ref 일반적인 값
watch(x, (newX) => {
console.log(`x is ${newX}`)
})
// 2. getter함수
watch(
() => x.value + y.value,
(sum) => {
console.log(`sum of x + y is ${sum}`)
}
)
// 3. array
watch([x, () => y.value], ([newX, newY]) => {
console.log(`x is ${newX}, y is ${newY}`)
})
반응형 객체의 속성은 볼 수 없다
// 숫자(number)를 전달하기 때문에 작동하지 않는다. const obj = reactive({ count: 0 }); watch(obj.count, (newValue) => { console.log('newValue:', newValue); })대신 getter를 사용하자
const obj = reactive({ count: 0 }); watch(() => obj.count, (newValue) => { console.log('newValue:', newValue); })
const person = reactive({
name: '홍길동',
age: 30,
hobby: '운동',
obj: {
count: 0
}
});
watch(person, (newValue) => {
console.log('newValue: ', newValue)
})
getter 함수로 객체를 넘길 경우에는 객체의 '값'이 바뀔 경우에만 트리거가 된다. 즉, 중첩된 속성은 트리거가 되지 않는다.
watch(() => person.obj, (newValue) => {
// 객체의 값자체가 바뀔 경우에만 트리거 된다.
})
deep 옵션을 사용하면 깊은 감시자로 강제할 수 있다.
watch(
() => person.obj,
(newValue) => {
console.log('newValue :', newValue);
},
{deep: true}
)
TIP) deep 옵션은 비용이 많이 들 수 있는 옵션이다. 필요한 경우에만 사용하고 성능영향에 주의하자
둘다 비슷한 역할을 하고 있다. 그러면 어떤 상황에서 이둘을 써야하는가?
computed: 단순 종속관계를 설정하려고 할 때는 watch가 아닌 computed를 쓰는 것이 적절.
watch: Vue 인스턴스의 상태(ref, reactive 변수)의 변경 시점에 특정 액션 (api call, push route 등)을 실행하려고 할때는 watch가 적절.
웬만한 상황에서는 watch보다 computed를 쓰는것을 먼저 고려해보자
watchEffect는 콜백 함수 안의 반응형 데이터의 변화가 감지되면 자동으로 반응하여 실행된다.
watchEffect(async () => {
const { data } = await axios.get('URL');
item.value = data.data;
})
watch와 watchEffect 둘다 반응형데이터를 감지해서 작업을 수행한다. 하지만 두개의 주요 차이점은 관련된 반응형 데이터를 추적하는 방식이다.
watch는 명시적으로 관찰된 데이터만 추적한다.
watchEffect는 콜백함수 안의 반응형 데이터를 자동으로 추적한다. 그리고 컴포넌트가 등장할때 watchEffect는 처음에 바로 실행된다.