728x90
storeToRefs()는 Pinia에서 ref()로 변환된 반응형 상태를 개별적으로 추출하는 함수입니다.
- Pinia 스토어의 state 속성들을 ref()로 변환하여 개별적으로 추출
- 반응형 유지 – storeToRefs()를 사용하면 ref()가 유지되므로 값이 변경될 때 UI가 자동으로 업데이트됨
- 객체 분해(구조 분해 할당) 시 반응성 유지
언제 storeToRefs()를 사용해야 할까?
상황 | storeToRefs() 필요 여부 |
state를 구조 분해 할 때 | ✅ 필요 |
state를 그대로 사용할 때 | ❌ 필요 없음 |
actions와 getters를 구조 분해 할 때 | ❌ 필요 없음 |
storeToRefs() 없이 사용하는 경우
Pinia 스토어에서 상태를 가져올 때, 구조 분해 할당을 직접 하면 반응성을 잃어버릴 수 있음.
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++;
}
}
});
storeToRefs() 없이 구조 분해 할당하면 반응성이 깨짐!
<script setup>
import { useCounterStore } from "~/store/counter";
const store = useCounterStore();
const { count } = store; // 반응성 깨짐!
console.log(count); // 0
store.increment();
console.log(count); // 여전히 0 (반응성 X)
</script>
왜 반응성이 깨질까?
- { count } = store에서 count는 일반 변수로 할당됨
- store.count가 변경되어도 { count } 변수는 자동으로 업데이트되지 않음
- Vue가 count의 변화를 감지할 수 없음
storeToRefs()를 사용하면?
Pinia의 state를 구조 분해 할당하면서도 반응성을 유지할 수 있습니다.
<script setup>
import { useCounterStore } from "~/store/counter";
import { storeToRefs } from "pinia";
const store = useCounterStore();
// ✅ storeToRefs() 사용하여 반응형 상태 유지
const { count } = storeToRefs(store);
console.log(count.value); // 0
store.increment();
console.log(count.value); // 1 (자동 업데이트)
</script>
storeToRefs()의 역할
- count가 ref()로 변환됨 (count = ref(store.count))
- count.value를 통해 값을 읽고, 변경 가능
- store.increment()가 실행되면 count.value도 자동으로 업데이트됨
storeToRefs()가 필요한 이유
Pinia의 state는 반응형이지만, 구조 분해 할당을 하면 반응성이 깨질 수 있음. 따라서 storeToRefs()를 사용해야 Vue가 상태 변경을 추적할 수 있습니다.
사용 방식 | 반응형 유지됨? | 설명 |
const count = store.count; | ❌ | count는 일반 변수로 변환되어 반응성 X |
const { count } = store; | ❌ | store.count의 값이 복사되므로 반응성 X |
const { count } = storeToRefs(store); | ✅ | store.count를 ref()로 변환하여 반응성 유지 |
storeToRefs() vs toRefs()
Vue의 toRefs()도 비슷한 역할을 하지만, Pinia에서는 반드시 storeToRefs()를 사용해야 합니다.
import { toRefs } from "vue";
import { storeToRefs } from "pinia";
const store = useCounterStore();
const { count } = storeToRefs(store); // ✅ 올바른 방법 (Pinia 전용)
// ❌ Vue의 toRefs()를 사용하면 actions, getters도 ref()로 변환되므로 비효율적!
const { count } = toRefs(store);
왜 storeToRefs()를 사용해야 할까?
- toRefs()를 사용하면 actions와 getters까지 ref()로 변환하려고 시도함 → 에러 발생 가능
- storeToRefs()는 Pinia의 state만 ref()로 변환하므로 안전함
storeToRefs()와 computed() 함께 사용하기
storeToRefs()를 활용하면 computed()와 결합하여 더 복잡한 상태를 만들 수도 있습니다.
<script setup>
import { useCounterStore } from "~/store/counter";
import { storeToRefs } from "pinia";
import { computed } from "vue";
const store = useCounterStore();
const { count } = storeToRefs(store);
// ✅ computed()와 함께 사용 가능
const doubleCount = computed(() => count.value * 2);
</script>
<template>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="store.increment">+</button>
</template>
count는 storeToRefs()로 ref()로 변환되었으므로, computed() 안에서 count.value를 사용하여 doubleCount를 만들 수 있습니다.
storeToRefs() 사용이 필요 없는 경우
1️⃣ 반응형 상태를 직접 사용할 때
<script setup>
import { useCounterStore } from "~/store/counter";
const store = useCounterStore();
</script>
<template>
<p>Count: {{ store.count }}</p> <!-- 직접 접근해도 반응성 유지됨 -->
</template>
2️⃣ actions나 getters만 구조 분해 할 때
반응형이 깨지는 것은 state일 때만 해당되므로, actions와 getters는 구조 분해 할당해도 괜찮습니다.
const { increment } = useCounterStore(); // actions는 storeToRefs()가 필요 없음
increment();
728x90
'Javascript > NuxtJS' 카테고리의 다른 글
[Nuxt3] Nitro (0) | 2025.03.15 |
---|---|
[Nuxt3] Server (0) | 2025.03.15 |
[Nuxt3] ref()와 computed() 차이점 (0) | 2025.03.12 |
[Nuxt3] 상태 관리 (0) | 2025.03.09 |
[Nuxt3] 라우트 미들웨어 (0) | 2025.03.09 |