본문 바로가기

FE

[vue3] nextTick() - DOM의 update flush를 기다리는 utility

vue로 개발을 하면서 ref 반응형 데이터의 값이 업데이트 되는 시점이 헷갈려서 찾아보니 nextTick() 이라는 

vue의 global API 함수를 알게되었다.

 

https://ko.vuejs.org/api/general

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 

1. 문제상황

공식문서의 예제를 살펴보면,

ref 반응형 변수를 업데이트 했을 때 DOM의 업데이트가 일어나지 않았을 경우

ref의 값을 바로 사용할 수 없다는 문제가 있다.

<script setup lang="ts">
import { ref, nextTick } from 'vue'

const count = ref(0);

async function increment() {
  count.value++;

  // 아직 DOM 업데이트되지 않음.
  console.log(document.getElementById('counter').textContent); // 0

  await nextTick();
  // 이제 DOM 업데이트됨.
  console.log(document.getElementById('counter').textContent); // 1
}
</script>

 


2. 해결

vue에서 제공하는 nextTick() 이라는 함수를 사용하면 DOM이 업데이트 되어

반응형 변수의 값이 업데이트 되었음을 보장하기 때문에 변경된 값을 사용할 수 있다.

function nextTick(callback?: () => void): Promise<void>

 

위의 예시처럼 await 을 사용하거나, callback을 사용하여 개발할 수 있다.

<script setup lang="ts">
import { ref, nextTick } from 'vue'

const count = ref(0);

function increment() {
  count.value++;

  nextTick(() => {
  	console.log(document.getElementById('counter').textContent); // 1
  });
}
</script>

 

+ 번외로 this.$nextTick() 을 사용할 수 있다.

https://ko.vuejs.org/api/component-instance.html#nexttick

 


3. 왜.. 그럴까..?

공식문서에 따르면 반응형 변수의 값을 변경한 결과는 동기적으로 DOM에 업데이트 되지 않는다고 한다.

→  비동기적으로 업데이트되면 반응형 변수의 값을 업데이트 하는 시점을 알 수 없기 때문에 이후 이 변수의 값을 사용할 때 업데이트 된 값을 사용할 수 있을지 보장할 수 없다는 것이다. 

 

"다음 틱"까지 버퍼링하여 얼마나 많은 상태 변경을 수행하든 각 컴포넌트가 한 번만 업데이트 되도록 한다.

nextTick() 은 반응형 변수 값이 업데이트 됐음을 보장하기 위해 사용한다.

 

더보기

공식문서

When you mutate reactive state in Vue, the resulting DOM updates are not applied synchronously. Instead, Vue buffers them until the "next tick" to ensure that each component updates only once no matter how many state changes you have made.

nextTick() can be used immediately after a state change to wait for the DOM updates to complete. You can either pass a callback as an argument, or await the returned Promise.

 


4. 그렇다면 문제는 없을까?

다음 DOM 업데이트까지 기다리기 때문에 nextTick()을 사용한다면 업데이트 반응이 느려질 것이다.

실제로 사용했을 때 api 호출이 늦어 보이는 현상이 발생하기 때문에.. 꼭 필요한 경우에 사용해야 할 것 같다.

 

- 반응형 값을 업데이트 하고 난 후 바로 그 값으로 api 호출을 해야할 때?

 

반응형 변수에 업데이트 할 값을 따로 생성한 후에 값을 할당하고 api 호출을 해도 되지만 코드가 더러워질 것 같다.. 

꼭 nextTick()을 사용해야하는지 다시 생각을..

 


5. vue에서 반응형 변수 업데이트를 동기로 개발하지 않은 이유는 무엇일까?

DOM의 생명주기를 모르기 때문에 현재 이 질문에 답할 수 없을 것 같다..

따라서 다음 글은 생명주기와 자바스크립트 동작 방식, vue 동작 방식에 대한 글로 다시 답하러 와야겠다..