FrameWorks/Vue

Vue의 watchEffect 와 watch 파헤치기

ABCD 2024. 6. 12.

watchEffect(${function}, {${options}} )

  • 컴포넌트 렌더링 직전에 실행된다.

  • 종속성을 반응형으로 추적하면서 함수를 즉시 실행하고 종속성이 변경될 때마다 함수를 다시 실행하는 함수

  • 기본 옵션값의 flush는 ‘pre’로 설정되어 있다.

  • 드물지만 캐시 무효화 등 반응형 의존성이 변경될 때 즉시 와처를 트리거해야 하는 경우

    • flush를 ‘sync’로 사용하여 수행할 수 있다.

      → 그러나, 여러 property가 동시에 업데이트 되는경우 성능 및 데이터에 문제를 야기할 수 있다.

  • Type

      function watchEffect(
        effect: (onCleanup: OnCleanup) => void,
        options?: WatchEffectOptions
      ): StopHandle
    
      type OnCleanup = (cleanupFn: () => void) => void
    
      interface WatchEffectOptions {
        flush?: 'pre' | 'post' | 'sync' // default: 'pre'
        onTrack?: (event: DebuggerEvent) => void
        onTrigger?: (event: DebuggerEvent) => void
      }
    
      type StopHandle = () => void
  • Side effect cleanup

      watchEffect(async (onCleanup) => {
        const { response, cancel } = doAsyncWork(id.value)
        //'ID'가 변경되면 '취소'가 호출되어 이전 보류 중인 요청이 아직 완료되지 않은 경우 취소됩니다.
        onCleanup(cancel)
        data.value = await response
      })
  • Stopping the watcher

      const stop = watchEffect(() => {})
    
      // 감시자가 더 이상 필요하지 않은 경우:
      stop()
  • 코드

      const count = ref(0)
    
      watchEffect(() => console.log(count.value))  // -> logs 0
    
      count.value++  // -> logs 1

watch(${var}, ${function})

  • 컴포넌트 렌더링 직전에 실행된다.

  • var의 값이 변경되면 function을 callback하는 함수

  • function의 parameter에 첫번째 인자는 받아온 ${var}의 Data, 두번째 인자는 원본 ${var}의 Data이다.

  • Type

      // watching single source
      function watch<T>(
        source: WatchSource<T>,
        callback: WatchCallback<T>,
        options?: WatchOptions
      ): StopHandle
    
      // watching multiple sources
      function watch<T>(
        sources: WatchSource<T>[],
        callback: WatchCallback<T[]>,
        options?: WatchOptions
      ): StopHandle
    
      type WatchCallback<T> = (
        value: T,
        oldValue: T,
        onCleanup: (cleanupFn: () => void) => void
      ) => void
    
      type WatchSource<T> =
        | Ref<T> // ref
        | (() => T) // getter
        | T extends object
        ? T
        : never // reactive object
    
      interface WatchOptions extends WatchEffectOptions {
        immediate?: boolean // default: false
        deep?: boolean // default: false
        flush?: 'pre' | 'post' | 'sync' // default: 'pre'
        onTrack?: (event: DebuggerEvent) => void
        onTrigger?: (event: DebuggerEvent) => void
      }
  • 코드

      <script type="module">
      import { createApp, ref, watch } from 'vue'
    
      createApp({
        setup() {
          const todoId = ref(1)
          const todoData = ref(null)
    
          async function fetchData() {
            todoData.value = null
            const res = await fetch(
              `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
            )
            todoData.value = await res.json()
          }
    
          fetchData()
    
          watch(todoId, fetchData)
    
          return {
            todoId,
            todoData
          }
        }
      }).mount('#app')
      </script>
    
      <div id="app">
        <p>Todo id: {{ todoId }}</p>
        <button @click="todoId++">Fetch next todo</button>
        <p v-if="!todoData">Loading...</p>
        <pre v-else>{{ todoData }}</pre>
      </div>
728x90
반응형

'FrameWorks > Vue' 카테고리의 다른 글

Vue의 Slot 파헤치기  (0) 2024.06.12
Vue의 Props 파헤치기  (0) 2024.06.12
Vue의 ModelValue 파헤치기  (0) 2024.06.12
Vue의 nextTick() 파헤치기  (0) 2024.06.12
Vue의 BaseHandler 파헤치기  (0) 2024.06.12

댓글

💲 추천 글