# 반응형(Reactivity) 기초

# 반응형 상태 선언하기

JavaScript 객체에서 반응형 상태를 생성하기 위해, reactive 메서드를 사용할 수 있습니다.

import { reactive } from 'vue'

// 반응형 상태
const state = reactive({
  count: 0
})
1
2
3
4
5
6

reactive 는 Vue 2.x 에서의 Vue.observable() API과 동일한 것으로, RxJS의 observables 과 혼동을 피하기 위해 이름을 바꿨습니다. 여기서 반환된 상태는 반응형 객체입니다. 반응형 변환은 "깊습니다" - 전달된 객체의 모든 중첩된 속성(property) 에 영향을 미친다는 의미입니다.

Vue 에서 반응형 상태를 위한 필수 사용 사례는 렌더링 중에 사용할 수 있다는 것입니다. 종속성 추적(dependency tracking) 덕분에, 반응형 상태가 변경될 때 화면은 자동적으로 업데이트될 것 입니다.

이것이 바로 Vue 의 반응형 시스템의 본질입니다. 컴포넌트의 data() 에서 객체를 반환할 때, 이것은 내부적으로 reactive() 에 의해 반응형으로 만들어집니다. 템플릿은 이러한 반응형 속성을 사용하는 렌더 함수 로 컴파일됩니다.

reactive에 대한 자세한 내용은 기본 반응형 API 들 섹션을 참고하십시오.

# refs로 독립적인 반응형 값 생성하기

독립적인 원시 값(예를 들어, 문자열 하나) 를 가지고 있고, 이것을 반응형으로 만들고자 하는 경우를 상상해봅시다. 물론 하나의 문자열을 속성으로 가지는 객체를 만들어서, 그것을 reactive로 던질 수도 있을 것 입니다. Vue는 동일하게 동작하는 메서드를 갖고 있습니다. 그것이 바로 ref 입니다.

import { ref } from 'vue'

const count = ref(0)
1
2
3

ref 는 반응형이면서 변이가능한(mutable) 객체를 반환합니다. 현재 갖고 있는 내부의 값에 대한 반응형 참조(reference)의 역할을 하며, 여기서 이름이 유래되었습니다. 이 객체는 오직 value 이라는 하나의 속성만 포함합니다.

import { ref } from 'vue'

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1
1
2
3
4
5
6
7

# Ref 포장 벗겨내기(Unwrapping)

ref 가 렌더 컨텍스트 (setup() 에서 반환된 객체) 에서 속성으로 반환되고 템플릿에서 접근되면, 자동적으로 내부 값을 풀어냅니다. 즉, 템플릿에서 .value 를 추가할 필요가 없다는 것입니다.

<template>
  <div>
    <span>{{ count }}</span>
    <button @click="count ++">카운트 증가</button>
  </div>
</template>

<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const count = ref(0)
      return {
        count
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 반응형 객체에서의 접근

ref가 반응형 객체의 속성으로 접근하거나 변이될 때, 자동적으로 내부 값으로 벗겨내서, 일반적인 속성과 마찬가지로 동작합니다.

const count = ref(0)
const state = reactive({
  count
})

console.log(state.count) // 0

state.count = 1
console.log(count.value) // 1
1
2
3
4
5
6
7
8
9

만약 새로운 ref 가 기존에 있던 ref 에 연결된 속성에 할당되면, 기존 ref 를 대체하게 됩니다.

const otherCount = ref(2)

state.count = otherCount
console.log(state.count) // 2
console.log(count.value) // 1
1
2
3
4
5

ref 포장 풀기는 반응형 Object 내부에서 중첩된 경우에만 발생합니다. ref 가 ArrayMap (opens new window) 과 같이 표준 내장 컬렉션 타입에서 접근된 경우에는 포장 벗겨내기(Unwrapping)가 동작하지 않습니다.

const books = reactive([ref('Vue 3 Guide')])
// 여기에는 .value 가 필요합니다.
console.log(books[0].value)

const map = reactive(new Map([['count', ref(0)]]))
// 여기에는 .value 가 필요합니다.
console.log(map.get('count').value)
1
2
3
4
5
6
7

# 반응형 상태 구조 분해하기(Destructuring)

큰 반응형 객체의 몇몇 속성을 사용하길 원할 때, 원하는 속성을 얻기 위해 ES6 구조 분해 할당 (opens new window) 을 사용하는 것이 유혹적일 수 있습니다.

import { reactive } from 'vue'

const book = reactive({
  author: 'Vue Team',
  year: '2020',
  title: 'Vue 3 Guide',
  description: '당신은 이 책을 지금 바로 읽습니다 ;)',
  price: '무료'
})

let { author, title } = book
1
2
3
4
5
6
7
8
9
10
11

안타깝게도, 그러한 구조 분해로 두 속성은 반응형을 잃게 될 것 입니다. 그런 경우, 반응형 객체를 일련의 ref 들로 변환해야 합니다. 이러한 ref 들은 소스 객체에 대한 반응형 연결을 유지합니다.

import { reactive, toRefs } from 'vue'

const book = reactive({
  author: 'Vue Team',
  year: '2020',
  title: 'Vue 3 Guide',
  description: '당신은 지금 바로 이 책을 읽습니다  ;)',
  price: '무료'
})

let { author, title } = toRefs(book)

title.value = 'Vue 3 상세 Guide' // title 이 ref 이므로 .value 를 사용해야 합니다.
console.log(book.title) // 'Vue 3 Detailed Guide'
1
2
3
4
5
6
7
8
9
10
11
12
13
14

refs 에 대한 자세한 내용은 Refs API 섹션을 참고하십시오.

# readonly 를 이용하여 반응형 객체의 변이 방지하기

때때로 반응형 객체(refreactive)의 변화를 추적하기 윈하지만, 또한 특정 부분에서는 변화를 막기를 원하기도 합니다. 예를 들어, 제공된 반응형 객체를 갖고 있을 때, 우리는 그것이 주입된 곳에서는 해당 객체가 변이되는 걸 막고자 할 것입니다. 이렇게 하려면 원래 객체에 대한 읽기 전용 프록시를 생성하십시오.

import { reactive, readonly } from 'vue'

const original = reactive({ count: 0 })

const copy = readonly(original)

// 원본이 변이되면 복사본에 의존하는 watch 도 트리거될 것 입니다.
original.count++

// 복사본을 변이하려고 하면 경고와 함께 실패할 것 입니다.
copy.count++ // warning: "Set operation on key 'count' failed: target is readonly."
1
2
3
4
5
6
7
8
9
10
11

Deployed on Netlify.
Last updated: 2021-01-13, 05:23:36 UTC