6 Vue3โœจ๐Ÿ›€์˜ ref ๋ฐ ๋ฐ˜์‘ํ˜• ์งˆ๋ฌธ์„ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

21522 ๋‹จ์–ด vuetutorialjavascriptwebdev
Vue3๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋‘ ๊ฐ€์ง€ APIref ๋ฐ reactive๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์ด API๋Š” Vue3 ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€ API์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์„œ์—์„œ๋Š” ์†Œ๊ฐœ ๊ด€์ ์—์„œ ์ด ๋‘ API๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ํ•จ๊ป˜ ํ† ๋ก ํ•˜๊ณ  ๋ฐฐ์šฐ์‹ญ์‹œ์˜ค ~

This article uses Vue3 setup syntax.



์ดˆ์‹ฌ์ž ๋‹จ๊ณ„์—์„œ ๋งˆ์Šคํ„ฐํ•ด์•ผ ํ•  ๊ฒƒ์€ ์ด ๋‘ API์˜ "๋ฌด์—‡", "์‚ฌ์šฉ ๋ฐฉ๋ฒ•"๋ฐ "๊ณตํ†ต ๋ฌธ์ œ"์ž…๋‹ˆ๋‹ค.

1. ๋ฆฌ์•กํ‹ฐ๋ธŒ API๋Š” ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋‚˜์š”?


reactive ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜์‘ํ˜• ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด/๋ฐฐ์—ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ฐ์ฒด์˜ ๋ฐ˜์‘ํ˜• ์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ฒด์˜ ์†์„ฑ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๊ฐœ์ฒด๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์œ„์น˜๊ฐ€ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด ๋ฐ ๋ฐฐ์—ด์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ:

import { reactive } from 'vue'

let reactiveObj = reactive({ name : 'Chris1993' });
let setReactiveObj = () => {
  reactiveObj.name = 'Hello Chris1993';
}

let reactiveArr = reactive(['a', 'b', 'c', 'd']);
let setReactiveArr = () => {
  reactiveArr[1] = 'Hello Chris1993';
}


ํ…œํ”Œ๋ฆฟ ์ฝ˜ํ…์ธ :

<template>
  <h2>Vue3 reactive API Base</h2>
  <div>
    Object:{{reactiveObj.name}} 
    <span @click="setReactiveObj">Update</span>
  </div>
  <div>
    Array:{{reactiveArr}} 
    <span @click="setReactiveArr">Update</span>
  </div>
</template>


ํŽ˜์ด์ง€ ๋‚ด์šฉ:


Update ๋ฒ„ํŠผ์„ ๊ฐ๊ฐ ํด๋ฆญํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋œ ํ›„ ๋ทฐ์˜ ์ฝ˜ํ…์ธ ๋„ ํ•จ๊ป˜ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



2. ์ฐธ์กฐ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?


ref์˜ ๊ธฐ๋Šฅ์€ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•(primitive data type)์„ ๋ฐ˜์‘ํ˜• ํŠน์ง•์„ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ ์œ ํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 7๊ฐœ์˜ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

JS/TS์—์„œ String์˜ ๊ฐ’์„ ์ฝ๊ณ  ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Number๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋ฉฐ ํ…œํ”Œ๋ฆฟ์—์„œ ์ฝ์„ ๊ฒฝ์šฐ์—๋Š” BigInt๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฌธ์ž์—ด๊ณผ ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ:

import { ref } from 'vue'

let refValue = ref('Chris1993');
let setRefValue = () => {
  refValue.value = 'Hello Chris1993';
}
let refObj = ref({ name : 'Chris1993' });
let setRefObj = () => {
  refObj.value.name = 'Hello Chris1993';
}


ํ…œํ”Œ๋ฆฟ ์ฝ˜ํ…์ธ :

<template>
  <h2>Vue3 ref API Base</h2>
  <div>
    String:{{refValue}} 
    <span @click="setRefValue">Update</span>
  </div>
  <div>
    Object:{{refObj.name}}
    <span @click="setRefObj">Update</span>
  </div>
</template>


ํŽ˜์ด์ง€ ๋‚ด์šฉ:


Boolean ๋ฒ„ํŠผ์„ ๊ฐ๊ฐ ํด๋ฆญํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋œ ํ›„ ๋ทฐ์˜ ์ฝ˜ํ…์ธ ๋„ ํ•จ๊ป˜ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



3. ์‹ฌ์ธต ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์— ๋Œ€ํ•ด reactive๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?



๋Œ€๋‹ต์€ ์˜ˆ์ž…๋‹ˆ๋‹ค. Symbol๋Š” ES2015 Proxy API์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„๋˜๋ฉฐ ์‘๋‹ต์„ฑ์€ ์ „์ฒด ๊ฐœ์ฒด์˜ ๋ชจ๋“  ์ค‘์ฒฉ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค.

๊ฐ์ฒด ๋ฐ ๋ฐฐ์—ด์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ:

import { reactive } from 'vue'

let reactiveDeepObj = reactive({
  user: {name : 'Chris1993'}
});
let setReactiveDeepObj = () => {
  reactiveDeepObj.user.name = 'Hello Chris1993';
}

let reactiveDeepArr = reactive(['a', ['a1', 'a2', 'a3'], 'c', 'd']);
let setReactiveDeepArr = () => {
  reactiveDeepArr[1][1] = 'Hello Chris1993';
}


ํ…œํ”Œ๋ฆฟ ์ฝ˜ํ…์ธ :

<template>
  <h2>Vue3 reactive deep API Base</h2>
  <div>
    Object:{{reactiveDeepObj.user.name}}
    <span @click="setReactiveDeepObj">Update</span>
  </div>
  <div>
    Array:{{reactiveDeepArr}}
    <span @click="setReactiveDeepArr">Update</span>
  </div>
</template>


ํŽ˜์ด์ง€ ๋‚ด์šฉ:


Null ๋ฒ„ํŠผ์„ ๊ฐ๊ฐ ํด๋ฆญํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋œ ํ›„ ๋ทฐ์˜ ์ฝ˜ํ…์ธ ๋„ ํ•จ๊ป˜ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



4. ๋ฐ˜์‘ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์†Œ์Šค ๊ฐ์ฒด์™€ ๊ฐ™์€๊ฐ€?


Undefined๊ฐ€ ES2015 Proxy API์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๋‹ต์€ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ๋Š” ํ”„๋ก์‹œ ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ:

let reactiveSource = { name: 'Chris1993' };
let reactiveData = reactive(reactiveSource);

console.log(reactiveSource === reactiveData);
// false

console.log(reactiveSource);
// {name: 'Chris1993'}

console.log(reactiveData);
// Reactive<{name: 'Chris1993'}>


5. TypeScript๋Š” ref ๋ฐ ๋ฐ˜์‘ ๋งค๊ฐœ๋ณ€์ˆ˜ ์œ ํ˜•์„ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•ฉ๋‹ˆ๊นŒ?



TypeScript๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ref/reactive ๋งค๊ฐœ๋ณ€์ˆ˜ ์œ ํ˜•์„ ์ž‘์„ฑํ•  ๋•Œ ref/reactive ์ธํ„ฐํŽ˜์ด์Šค ์œ ํ˜•์— ๋”ฐ๋ผ ํŠน์ • ์œ ํ˜•์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function ref<T>(value: T): Ref<T>

function reactive<T extends object>(target: T): UnwrapNestedRefs<T>


์ด์ „ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

import { ref } from 'vue'

let refValue = ref<string>('Chris1993');

let setRefValue = () => {
  refValue.value = 'Hello Chris1993'; // ok!
  refValue.value = 1993; // error!
}

let reactiveValue = reactive<{name: string}>({name: 'Chris1993'});


6. ๋ฐ˜์‘ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ์„œ์˜ ref ๊ฐ’์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?



์ด๋ฏธ ref ๊ฐ์ฒด๊ฐ€ ์žˆ๊ณ  ์ด๋ฅผ .value ๊ฐ์ฒด์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

๊ฐ€์ •ํ•˜๋‹ค:

let name = ref('Chris1993');
let nameReactive = reactive({name})


๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

let name = ref('Chris1993');
let nameReactive = reactive({name})
console.log(name.value === nameReactive.name); // true

name.value = 'Hello Chris1993';
console.log(name.value);        // Hello Chris1993
console.log(nameReactive.name); // Hello Chris1993

nameReactive.name = 'Hi Chris1993';
console.log(name.value);        // Hi Chris1993
console.log(nameReactive.name); // Hi Chris1993


์ด๋Š” .value๊ฐ€ ๋ชจ๋“  ๋”ฅUpdate์˜ ์••์ถ•์„ ํ’€๊ณ  reactive๋ฅผ ๋ฐ˜์‘ํ˜•์œผ๋กœ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
Update๊ฐ€ ํ• ๋‹น์— ์˜ํ•ด reactive ์†์„ฑ์— ํ• ๋‹น๋˜๋ฉด ref๋„ ์ž๋™์œผ๋กœ ์••์ถ• ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค.

let name = ref('Chris1993');
let nameReactive = reactive({})
nameReactive.name = name;

console.log(name.value);        // Chris1993
console.log(nameReactive.name); // Chris1993
console.log(name.value === nameReactive.name); // true


7. ์š”์•ฝ



์ด ๊ธ€์€ ์ฃผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ด€์ ์—์„œ reactive/reactive API ์‚ฌ์šฉ์˜ ์ฐจ์ด์ ๊ณผ ์‚ฌ์šฉ ํ”„๋กœ์„ธ์Šค์˜ ์—ฌ๋Ÿฌ ๋ฌธ์ œ์ ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„๋‹จํžˆ ์š”์•ฝํ•˜์ž๋ฉด:
  • refs๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ์ฒด/๋ฐฐ์—ด ์œ ํ˜• ๋ฐ์ดํ„ฐ์— ์‚ฌ์šฉ๋˜๋ฉฐ ref๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ref๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์˜ ๋ฐ์ดํ„ฐ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. JS์—์„œ ์ฝ๊ณ  ์ˆ˜์ •ํ•  ๋•Œ reactive ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ํ…œํ”Œ๋ฆฟ์—์„œ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ref๋Š” ๊นŠ์€ ์†์„ฑ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๊ณ  ์‘๋‹ต์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • reactive ๋ฐ˜ํ™˜ ๊ฐ’์ด ์†Œ์Šค ๊ฐœ์ฒด์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
  • ref ์†์„ฑ ๊ฐ’์€ reactive ๊ฐ’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค์Œ ๊ธฐ์‚ฌ์—์„œ๋Š” ์ˆ™๋‹ฌ๋œ ๋‚ด์šฉ์„ ๊ณต์œ ํ•  ๊ฒƒ์ด๋ฉฐ ๊ธฐ๋Œ€ํ•˜์…”๋„ ์ข‹์Šต๋‹ˆ๋‹ค.

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ