Pinia

Pinia 3

Hoon1994 2022. 9. 5. 16:33

Pinia Logo

 

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에 대해 포스팅할 예정이다!