동적 Vuex 게터

고차 함수(Higher-order_function)를 사용해 Vuex에서 동적 게터를 만드는 방법을 살펴 보겠습니다. 동적 게터는 게터에 인자를 전달할 수 있습니다. 이런 방법은 인자를 전달해 스토어를 조회할 때 유용합니다.

일반적인 사용 예는 id를 전달해 스테이트에서 아이템을 찾는 게터입니다.

getters: {
  getBookById(state) {
    return (id) => {
      return state.books.find(book => book.id === id);
    }
  },
}

NOTE

화살표 함수를 사용해 다음과 같이 작성할 수도 있습니다.

getters: {
  getBookById: state => id => state.books.find(book => book.id === id),
}

판매 가능한 도서만 표시하던 대신 '카트에 추가' 버튼을 비활성화 하는 방향으로 전환하기 위해 컴포넌트에 사용된 스토어의 availableBooks 코드를 제거하고, 모든 도서를 화면에 표시하도록 스토어의 books 스테이트로 변경합니다.

// components/BookList.vue

export default {
  name: 'BookList',
  computed: {
    books() {
      // return this.$store.getters.availableBooks;
      return this.$store.state.books;
    }
  },
  // ...
}

도서 재고가 없을 경우 품절(Out of Stock)로 버튼을 사용할 수 없도록 설정해봅니다.

버튼의 disabled 속성을 동적으로 설정하는 게터 checkOutOfStock를 설정하고, 인자로 book을 전달하는 코드를 작성합니다. 컴포넌트의 계산된 속성 checkOutOfStock은 스토어의 checkOutOfStock 게터를 반환하도록 설정합니다.












 










 
 
 




<!-- components/BookList.vue -->

<template>
  <div class="book-list">
    <!-- ... -->
    <ul v-else>
      <li v-for="(book,i) in books" :key="i">
        {{ book.name }} / {{ book.price | won }}
        <button
          type="button"
          @click="addBookToCart(book)"
          :disabled="checkOutOfStock(book)"
        >카트에 추가</button>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "BookList",
  computed: {
    checkOutOfStock() {
      return this.$store.getters.checkOutOfStock;
    }
  },
}
</script>

NOTE

'Sold Out'과 'Out of Stock'의 의미는 다소 다릅니다.

용어 설명
매진(sold out) 판매 가능하지 않은
품절(out of stock) (일시적으로) 재고가 없는

스토어에 checkOutOfStock 동적 게터를 추가한 후, 반환되는 함수의 매개변수로 도서(book)을 설정합니다. 동적 게터를 통해 전달 받은 book의 재고가 0일 경우 true를 아닐 경우 false를 반환합니다.

// store/index.js
getters: {
  checkOutOfStock(state) {
    return book => {
      return book.inventory === 0;
    }
  },
}

NOTE

다음과 같이 코드를 변경할 수 있습니다.

getters: {
  checkOutOfStock: state => book => book.inventory === 0
}

스토어의 addBookToCart 액션 코드에서도 동적 게터를 활용할 수 있습니다. 액션의 첫번째 인자에서 getters를 추가한 후, 조건으로 동적 게터를 활용한 예입니다.




 

 






// store/index.js

actions: {
  addBookToCart({state, getters, commit}, book) {
    // if (book.inventory > 0) {
    if (!getters.checkOutOfStock(book)) {
      // ...
    }
  },
  // ...
}