toRef, toRefs
Front-end VuetoRef
?
toRef()
는 반응형 객체의 속성을 하나의 ref
객체로 만들 때 사용한다.
생성된 ref
객체는 원본 반응형 객체의 속성과 동기화된다. 원본 속성을 변경하면 ref
객체가 업데이트되며, 그 반대의 경우도 마찬가지이다.
const state = reactive({ foo: 1, bar: 2 })
const fooRef = toRef(state, 'foo')
// 참조를 변경하면 원본이 업데이트됩니다.
fooRef.value++
console.log(state.foo) // 2
// 원본을 변경하면 ref도 업데이트됩니다.
state.foo++
console.log(fooRef.value) // 3
ref
, toRef
의 차이
const fooRef = ref(state.foo)
위 예제의 ref
객체(fooRef
)는 primitive 값을 초기화 값으로 받기 때문에 state.foo
와 동기화되지 않는다.
toRef
활용
toRef()
는 Composable 함수에 Props 참조를 전달하는 경우에 유용하다.
import {toRef} from 'vue'
const props = defineProps(/* ... */)
// props.foo를 ref형태로 변환한 다음 composable에 적용
useMyFeature(toRef(props, 'foo'))
toRef()
가 props
와 함께 사용되면 props
변경에 대한 제한사항이 적용된다. ref
에 새 값을 할당하려는 시도는 prop
을 직접 수정하려는 것과 동일하게 판단되며 허용되지 않는다.
새 값을 할당하려는 상황이라면 toRef()
대신
computed(get, set)`를 활용하는 것이 좋다.
그리고 toRef
는 반응형 객체의 속성이 존재하지 않아도 사용 가능한 ref
객체를 반환한다.
toRefs
?
반응형(reactive) 객체를 구조분해할당 후 반응형을 그대로 유지하려고 할 때 한다.
반응형 객체를 구조분해하여 재할당 할 경우 반응형으로 동작하지 않는다. (call by value가 되기 때문)
let position = reactive({ x: 0, y: 0, })
let { x, y } = position
x++
y++
console.log(x, y) // 1 1
console.log(position.x, position.y) // 0 0
이 때 반응성을 유지하기 위해 reactive
객체의 각각의 속성을 ref
로 변환해 주는 것이 toRefs()
이다.
toRefs
를 사용하면 reactive
객체 각각의 속성이 ref
값으로 변환된다. 그렇기 때문에 구조분해할당으로 재할당을 받게 되면 재할당 받은 ref
참조 값(예제에서는 x
, y
)과 reactive
객체의 속성이 동기화된다.
let position = reactive({ x: 0, y: 0, })
let { x, y } = toRefs(position)
x.value++
y.value++
console.log(x.value, y.value) // 1 1
console.log(position.x, position.y) // 1 1
toRefs
활용
toRefs()
는 일반 함수나 Composable 함수에서 Reactive 객체를 반환받는 경우에 유용하게 사용된다.
const useMyFeature = () => {
const state = reactive({ foo: 1, bar : 2 })
/* composable fn logic operating on state ... */
return toRefs(state) // refs 형태로 반환
}
const { foo, bar } = useMyFeature() // reactivity 를 가진 채 구조분해할당 가능
Composable 함수 내에서 반환값을 ref
로 반환해야 하는 컨벤션이 있다.
하지만 Composable 함수 내에서 reactive
객체를 사용하고 싶을 때가 있을 때는 toRefs()
함수를 사용하여 내부에서 사용한 reactive
객체를 ref
로 변환하여 반환할 수 있다.