# Vuex가 무엇인가요?

Vuex는 Vue.js 애플리케이션에 대한 **상태 관리 패턴 + 라이브러리** 입니다. 애플리케이션의 모든 컴포넌트에 대한 중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있습니다. 또한 Vue의 공식 [devtools 확장 프로그램](https://github.com/vuejs/vue-devtools)과 통합되어 설정 시간이 필요 없는 디버깅 및 상태 스냅 샷 내보내기/가져오기와 같은 고급 기능을 제공합니다.

### "상태 관리 패턴"이란 무엇인가요?

간단한 Vue 카운터 앱부터 시작 해보겠습니다.

``` js
new Vue({
  // 상태
  data () {
    return {
      count: 0
    }
  },
  // 뷰
  template: `
    <div>{{ count }}</div>
  `,
  // 액션
  methods: {
    increment () {
      this.count++
    }
  }
})
```

다음과 같은 기능을 가진 앱입니다.

- **상태** 는 앱을 작동하는 원본 소스 입니다.
- **뷰** 는 **상태의** 선언적 매핑입니다.
- **액션** 은 **뷰** 에서 사용자 입력에 대해 반응적으로 상태를 바꾸는 방법입니다.

이것은 "단방향 데이터 흐름" 개념의 매우 단순한 도표입니다.

<p style="text-align: center; margin: 2em">
  <img style="width:100%;max-width:450px;" src="./images/flow.png">
</p>

그러나 **공통의 상태를 공유하는 여러 컴포넌트** 가 있는 경우 단순함이 빠르게 저하됩니다.

- 여러 뷰는 같은 상태에 의존합니다.
- 서로 다른 뷰의 작업은 동일한 상태를 반영해야 할 수 있습니다.

첫번째 문제의 경우, 지나치게 중첩된 컴포넌트를 통과하는 prop는 장황할 수 있으며 형제 컴포넌트에서는 작동하지 않습니다. 두번째 문제의 경우 직접 부모/자식 인스턴스를 참조하거나 이벤트를 통해 상태의 여러 복사본을 변경 및 동기화 하려는 등의 해결 방법을 사용해야 합니다. 이러한 패턴은 모두 부서지기 쉽고 유지보수가 불가능한 코드로 빠르게 변경됩니다.

그렇다면 컴포넌트에서 공유된 상태를 추출하고 이를 전역 싱글톤으로 관리해야 합니다. 이를 통해 우리의 컴포넌트 트리는 커다란 "뷰"가 되며 모든 컴포넌트는 트리에 상관없이 상태에 액세스하거나 동작을 트리거 할 수 있습니다!

또한 상태 관리 및 특정 규칙 적용과 관련된 개념을 정의하고 분리함으로써 코드의 구조와 유지 관리 기능을 향상시킵니다.

이는 [Flux](https://facebook.github.io/flux/docs/overview), [Redux](http://redux.js.org/), [The Elm Architecture](https://guide.elm-lang.org/architecture/)에서 영감을 받은 Vuex의 기본 아이디어 입니다. 다른 패턴과 달리 Vuex는 Vue.js가 효율적인 업데이트를 위해 세분화된 반응 시스템을 활용하도록 특별히 고안된 라이브러리입니다.

![vuex](./images/vuex.png)

### 언제 사용해야 하나요?

Vuex는 공유된 상태 관리를 처리하는 데 유용하지만, 개념에 대한 이해와 시작하는 비용도 함께 듭니다. 그것은 단기간과 장기간 생산성 간의 기회비용이 있습니다.

대규모 SPA를 구축하지 않고 Vuex로 바로 뛰어 들었다면, 시간이 오래 걸리고 힘든일일 것입니다. 이것은 일반 적인 일입니다. 앱이 단순하다면 Vuex없이는 괜찮을 것입니다. 간단한 [글로벌 이벤트 버스](https://kr.vuejs.org/v2/guide/components.html#비-부모-자식간-통신)만 있으면됩니다. 그러나 중대형 규모의 SPA를 구축하는 경우 Vue컴포넌트 외부의 상태를 보다 잘 처리할 수 있는 방법을 생각하게 될 가능성이 있으며 Vuex는 자연스럽게 선택할 수 있는 단계가 될 것입니다. Redux의 저자인 Dan Abramov의 좋은 인용이 있습니다.

> Flux 라이브러리는 안경과 같습니다. 필요할 때 알아볼 수 있습니다.
