Vue

[Vue 3] computed(() => ) 와 storeToRefs() 의 차이?

Anchovy ʕ-᷅ᴥ-᷄ʔ 2025. 1. 9. 18:36

 

안녕하세요?🦖

 

vue 3에서 computed(() => )와 storeToRefs()의 차이에 대해 알아보려고 합니다.

무작정 사용하다 보면 비슷한 거 같지만 다른 거 같은데 혹시 정확한 차이가 뭔지 아시나요?

이 둘은 비슷한 목적을 가지고 있지만, 동작 방식에 차이가 있습니다. 각각의 차이를 살펴보겠습니다!

 

 

1. computed(() => ) 방식

const option = computed(() => appOptionStore.getOption)
computed를 사용하여 appOptionStore.getOption를 반응형으로 감싸는 방식

appOptionStore.getOption는 Pinia 스토어의 getter로, computed는 반응형 값을 반환하는 데 사용
이 방식은 appOptionStore.getOption가 computed로 정의되어 있는 경우에 적합
즉, option은 appOptionStore.getOption의 값을 반응형으로 추적

- computed를 사용하여 userRoles를 명시적으로 정의해야 함

 

 

2. storeToRefs() 방식

const { getOption } = storeToRefs(appOptionStore)
storeToRefs는 Pinia 스토어의 모든 상태를 ref로 감싸고, 이를 reactive한 방식으로 사용할 수 있도록 변환

storeToRefs는 자동으로 모든 반응형 값을 반환하므로 더 간편하게 사용
그러나 이 방식은 반응형 속성을 ref로 감싸기 때문에, computed와는 약간 다르게 동작할 수 있음

 

 

3. 정리

방식 설명 동작 방식
computed(() => ) computed로 감싸 반응형 상태 추적 getOption를 computed로 감싸서 값이 변경될 때마다 자동 추적
storeToRefs() storeToRefs를 사용하여 ref로 변환 getOption를 reactive ref로 변환하여 상태 추적

 

동작 면에서는 유사하지만,

computed 방식은 computed의 특성을 활용하는 방식이고, storeToRefs는 Pinia 상태를 ref로 변환하여 사용하는 방식
두 방식은 목적은 비슷하나, 사용하려는 store의 구조와 반응형 추적 방식의 차이

 

 

 

※ 구현 방식이 이미 computed라면?

이미 store에 computed로 정의되어 있다면 단순 접근해서 사용, computed를 중첩해서 쓸 필요는 없음.

const userStore = useUserStore();
const userRoles = computed(() => userStore.getRoles); // 불필요!

 

 

※ watch() 를 위해 사용하는 경우라면?

선언하여 사용하는 경우, 다른 값이 나올 수 있으니 선언하는 위치를 잘 생각해야 한다.

<script setup>
import { watch } from 'vue'
import { useUserStore } from '@/stores/userStore';
import { storeToRefs } from 'pinia';

const userStore = useUserStore();
const { getIsAuthenticated } = storeToRefs(userStore);
const isAuthenticated = userStore.getIsAuthenticated;

// 로그인 상태 변경 감지
watch(
  getIsAuthenticated,
  async (loggedIn) => {
    console.log('watch getIsAuthenticated: ', getIsAuthenticated.value);
    console.log('watch isAuthenticated: ', isAuthenticated);
    console.log('watch isAuthenticated: ', userStore.getIsAuthenticated);
    if (loggedIn) {
      ...
    }
  }
);
</script>

// watch getIsAuthenticated: true
// watch isAuthenticated: false
// watch isAuthenticated: true