Vue3 ref() & reactive()

wonyu·2023년 8월 22일

ref()

import { ref } from 'vue'

const count = ref(0)
console.log(count.value)
  • 내부 값을 받아 반응형이고 변경 가능한 ref object를 반환한다.
  • 내부 값을 가리키는 .value 프로퍼티를 갖는다.
  • ref object는 변경 가능(mutable)하다. 따라서 .value 에 새 값을 할당할 수 있다.
  • 반응형이다. 즉, .value에 대한 모든 읽기 작업이 추적되고 쓰기 작업이 관련 효과를 트리거 한다.
  • 객체가 ref의 값으로 할당되면 객체는 reactive()를 사용하여 deeply reactive해진다.
    • 즉, 중첩된 객체나 배열을 변경하더라도 변경사항이 감지될 것이다.
    • deep reactivity를 제거하려면 shallowRef()를 사용한다.
      • 얕은 참조를 사용할 경우 반응성을 위해 .value만 추적된다.
      • 거대한 객체 또는 내부 state가 외부 라이브러리에 의해 관리되는 경우 성능을 최적화하는 데 사용할 수 있다.
  • 모든 타입에 대해 사용 가능하다.

reactive()

import { reactive } from 'vue'

const state = reactive({ count: 0 })
console.log(state.count)
  • 원본 객체의 반응형 proxy를 반환한다.
    • 즉 원본 객체에 대한 작업을 가로채는 것으로, 원본 객체와 같지 않다.
    • 또한 proxy만 반응형이기 때문에, 원본 객체를 변경해도 업데이트가 트리거되지 않는다.
      const raw = {}
      const proxy = reactive(raw)
      // proxy는 원본과 동일하지 않다.
      console.log(proxy === raw) // false
  • 객체의 내부 값을 래핑하는 ref와 달리 객체 자체를 반응형으로 만든다.
    • 중첩된 객체 또한 접근할 때 reactive로 래핑된다.
      -shallow refs와 유사하게 deep reactivity를 제거하기 위한 shallowReactive()가 존재한다.
  • 객체 타입(객체, 배열, Map이나 Set 같은 collection types)에 대해서만 사용 가능하다.
    • 원시 타입의 값에 대해 사용할 수 없다.
  • destructuring을 하거나 속성을 함수의 인자로 전달하는 경우 반응성 연결이 끊어진다.

Vue 공식문서에서는 반응형 상태를 선언할 때 가장 좋은 방법은 상태의 proxied version만을 사용하는 것이라고 언급하고 있다. 하지만 reactive()의 몇 가지 제한 사항 때문에 기본적으로 ref()를 사용하는 것을 권장하고 있다.


현재 서비스에서는 모든 반응형 상태를 선언할 때 ref()를 사용하고 있다.
두 함수를 비교해본 결과 Menu, Option처럼 많은 속성과 메서드를 가진 클래스 인스턴스나 API 응답 데이터같은 경우 reactive()를 사용하면 성능을 개선할 수 있지 않을까 생각한다.


0개의 댓글