반응형 데이터
반응형 데이터 ref와 reactive에 대하여
reactive와 ref
1. reactive
<h2>
객체나 배열과 같은 데이터를 반응형으로 만들려면 `reactive`를 사용해야한다
</h2>
<button v-on:click="increament">Click !! Count: {{ state.count }} </button>
setup(){
const state = reactive({
count: 0,
});
const increament = () => {
++state.count;
};
}
2. reactive - primitive
원시데이터(number, string)의 경우 reactive로 감싸면 동작하지않는다
그이유는 object type만 받기때문이다.
reactive <type of Object>
let primitiveData = reactive('테스트데이터');
const increamentPrimitiveData = () => {
primitiveData = primitiveData + '!';
console.log(primitiveData);
};
<h2>원시데이터는 reactive를 사용하면 문제가 생긴다</h2>
<button @click="increamentPrimitiveData">
primitiveData = {{ primitiveData }} , 클릭하면 !가 붙는다.
</button>
console
테스트데이터!
테스트데이터!!
테스트데이터!!!
3. wrapping해서 reactive사용하여 primitive Data 사용
이를 해결하기 위해서는 Object형으로 한번더 감아서 선언해야한다.
let primitiveDataByObject = reactive({
value: '객체로 한번 더 감싼 원시데이터입니다',
});
const increamentPrimitiveDataByObject = () => {
primitiveDataByObject.value = primitiveDataByObject.value + '!';
};
<h2>그래서 객체로 사용해야한다.</h2>
<button @click="increamentPrimitiveDataByObject">
클릭하면 {{ primitiveDataByObject.value }} 에서 !가 붙습니다.
</button>
4. refs
결국 위와 같이 Wrapping을 이용한 Object인 refs가 나타난다
let refData = ref('refData입니다');
const increamentRefData = () => {
refData.value = refData.value + '!'; //value를 붙여야함
};
<h2>
이것을 간단하게 만든 것이 ref이다. ref의 내부를 보면 결국 ref는
object인것을 알 수 있다.
</h2>
<button @click="increamentRefData">
클릭하면 {{ refData }} 에서 !가 붙습니다. <!-- {{}} 안에는 value를 안붙어도 알아서 value가 붙은걸로 인식한다.-->
</button>
ref와 reative 동시사용
1. reactive의 object 필드값으로 ref를 사용
ref 변수를 reactive의 필드값으로 사용하면 .value를 붙이지 않아도 된다.
const count = ref(0);
const countState = reactive({
count, //key value가 서로 같으면 생략가능 = count: count,
});
count.value++;
count.value++;
countState.count++;
//countState.count.value++; error
console.log('ref를 reactive-object에서 사용할땐 value를 붙이지 않는다');
console.log('count.value', count.value);
console.log('countState.count.value', countState.count.value); //undefined가 뜬다
console.log('countState.count', countState.count);
console
ref를 reactive-object에서 사용할땐 value를 붙이지 않는다
count.value 3
countState.count.value undefined
countState.count 3
결국 ref변수가 필드로 사용되건, 일반 변수가 필드로 사용되건 .value가 사용하면 안된다.
cf) ref와 reactive type
console.log('count: ', count);
console.log('countState:', countState);
reactive안에서의 property를 ref로 선언했어도 countState.count처럼 표현식으로 사용하면 반응형이 사라진다.
위에서 console.log(countState.count)를 확인했을때 refImpl과 관련된건 나타나지않은 것을 확인 할 수 있다.
하지만 {{ countState.count }}와 같이 템플릿 문법안에서는 정상적으로 반응형이 유지된다.
2. reactive의 array 필드값으로 ref를 사용
Array의 원소값으로 ref를 사용하면 value를 사용해야한다
//Array의 원소값으로 ref를 넣을 때
const refData2 = ref('ref content');
const reactiveData2 = reactive([refData2]);
console.log(reactiveData2[0].value);
console.log(reactiveData2[0]); //ref로 반환
//Array의 원소값으로 일반 string을 넣을 때
const reactiveData2_1 = reactive(['hello']);
console.log('reactiveData2_1[0].value', reactiveData2_1[0].value);
console.log('reactiveData2_1[0]', reactiveData2_1[0]);
반응성
1. reactive의 필드값을 다른 곳에서 대입하여 사용하면 반응성을 잃는다
const reactiveData3 = reactive({
testData: 'hello',
testData2: 'World',
});
let normalData = reactiveData3.testData; //반응성이 없는 데이터 normalData
const function1 = () => {
normalData = normalData + '!';
console.log('normalData', normalData);
console.log('reactiveData3.testData', reactiveData3.testData);
}
const function2 = () => {
reactiveData3.testData = reactiveData3.testData + '!';
console.log('normalData', normalData);
console.log('reactiveData3.testData', reactiveData3.testData);
}
<h2>반응형객체의 필드를 변수명에 대입하여 사용하면 반응형이 먹히지않는다</h2>
<button @click="function1">reactiveData3.testData: {{ reactiveData3.testData }}, normalData: {{ normalData }} </button>
<button @click="function2">reactiveData3.testData: {{ reactiveData3.testData }}, normalData: {{ normalData }} </button>
function1 버튼을 4번 클릭시
normalData hello!
reactiveData3.testData hello
normalData hello!!
reactiveData3.testData hello
normalData hello!!!
reactiveData3.testData hello
normalData hello!!!
reactiveData3.testData hello
console에는 정상적으로 !가 추가된다
function2 버튼을 4번 클릭시
normalData hello!!!!
reactiveData3.testData hello!
normalData hello!!!!
reactiveData3.testData hello!!
normalData hello!!!!
reactiveData3.testData hello!!!
console에는 정상적으로 !가 추가된다
2. 반응성 유지:toRef
반응성을 유지하기위해서는 toRef를 사용한다
const reactiveData4 = reactive({
testData: 'hello',
testData2: 'World',
});
let helloData = toRef(reactiveData4, 'testData'); //toRef를 쓰면 Ref형이된다.
const function3 = () => {
helloData.value += '!';
console.log('helloData.value', helloData.value);
console.log('reactiveData4.testData', reactiveData4.testData);
}
<h2>toRef를 사용하여 해결한다</h2>
<button @click="function3"> {{ reactiveData4.testData }} , {{ helloData }} </button>
ReadOnly
복제를 해서 사용할 경우
const original = reactive({
count: 0,
});
const copy = original; //필드값을 전달할때는 반응성을 잃지만 객체그대로 보내면 반응성 유지
const changeOriginal = () =>{
copy.count++;
}
<h2>readOnly 사용안할때</h2>
<button @click="changeOriginal"> {{ original }}, {{ copy }} </button>
readonly
const original = reactive({
count: 0,
});
const copy2 = readonly(original);
const changeOriginal2 = () =>{
copy2.count++;
}
<h2>readOnly 사용</h2>
<button @click="changeOriginal2">, </button>
댓글 쓰기