Getters
이번 포스팅에서는 Pinia의 Getters에 대해 알아보고자 한다.
Pinia 자체가 Vuex & Composition API와 문법이 매우 비슷해서 문법 자체는 크게 어렵지 않은 것 같다.
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0, name:'ethan' }),
getters: {
doubleCount: state => state.count * 2
},
})
export const useCounterStore = defineStore('counter', () => {
const count = ref(2);
const name = ref('ethan');
const doubleCount = computed(() => count.value * 2);
return { count, name, doubleCount };
})
컴포넌트에서 사용할 땐 아래와 같이 사용할 수 있다.
<template>
<p>Double count is {{ store.doubleCount }}</p>
</template>
<script>
export default {
setup() {
const store = useCounterStore()
return { store }
},
}
</script>
getter 내부에서 다른 getter에 접근할 때는 this를 써서 접근할 수 있다.
Composition API 사용 이후에 Vue에서 this를 거의 사용할 일이 없었는데 Pinia에서는 사용되는 것 같다.
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
getters: {
// type is automatically inferred because we are not using `this`
doubleCount: (state) => state.count * 2,
// here we need to add the type ourselves (using JSDoc in JS). We can also
// use this to document the getter
/**
* Returns the count value times two plus one.
*
* @returns {number}
*/
doubleCountPlusOne() {
// autocompletion ✨
return this.doubleCount + 1
},
},
})
주의할 점은 화살표 함수를 사용할 경우 this가 바인딩되지 않아 undefined로 떨어지니
this를 사용해야 한다면 일반 함수 문법으로 작성해야 한다.
getters는 보통 인자를 받지 않지만,getter 함수가 함수를 리턴하는 경우 인자를 받을 수 있다.
다만, 이 경우 값이 캐싱되지 않는 점 참고해야 하며, getter 내부에서는 일부 캐시할 수 있다고 한다.
성능적으로는 더 좋다고 하는데... 이는 조금 더 깊게 파봐야 할 것 같다.
export const useStore = defineStore('main', {
getters: {
getActiveUserById(state) {
const activeUsers = state.users.filter((user) => user.active)
return (userId) => activeUsers.find((user) => user.id === userId)
},
},
})
<script>
export default {
setup() {
const store = useStore()
return { getUserById: store.getUserById }
},
}
</script>
<template>
<p>User 2: {{ getUserById(2) }}</p>
</template>
다른 스토어의 getters에 접근해야 할 때, Vuex에서는 RootGetters를 사용했는데, Pinia에서는 스토어를 불러오는 방식을 사용한다.
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})
다음에는 actions에 대해 포스팅할 예정이다!