hubring

[Vue] Vuex 란? 본문

Javascript/Vue.js

[Vue] Vuex 란?

Hubring 2019. 5. 6. 01:27

Vuex

Vue.js 애플리케이션에 대한 상태 관리(state management)를 돕는 라이브러리이다.

애플리케이션의 모든 컴포넌트에 대한 중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있다.

Vue의 공식 devtools 확장 프로그램과 통합되어 설정 시간이 필요 없는 디버깅 및 상태 스냅 샷과 같은 고급 기능을 제공한다.

 

상태 관리란?

상태(state)란 뷰 data 속성과 비슷하다.

ex) 간단한 Vue 카운터 앱

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

상태 :  앱의 상태를 나타내는 데이터
뷰 : 상태와 매핑되어 화면으로 나타냄
액션 : 뷰에서 사용자의 입력에 의하여 상태를 변경

단반향인 경우의 흐름은 아래와 같이 매우 단순하게 표현 가능하다.

단반향 데이터 흐름 도표

하지만 공통의 상태(ex: count)를 공유하는 여러 컴포넌트가 생길 경우 위 단순한 흐름이 복잡하게 변하게 된다.

컴포넌트가 너무 많을 경우

위 그림과 같이 된다면 뷰에서 컴포넌트 간의 데이터 전달 방법인 props로 데이터를 전달한다고 할 때 가장 하위 컴포넌트와 최상위 컴포넌트 사이에 있는 모든 컴포넌트에 props를 설정해 주어야 한다. 만약 데이터의 변경이 생길 경우 연관된 모든 컴포넌트에 대해 수정이 일어날 수 있다.

이때 props 대신 이벤트 버스를 사용하면 상하위 간의 데이터 전달 구조를 따르지 않고 한 번에 데이터를 보낼 수 있다. 하지만 그 흐름이 단반향이 아닌 아래 그림과 같이 많은 데이터 흐름이 존재한다면 데이터를 관리하는 데 어려움이 발생할 것이다.

데이터 흐름 규칙이 정해지지 않을 경우

 

이러한 패턴은 모두 부서지기 쉽고 유지보수가 불가능한 코드로 빠르게 변경된다.

이 문제를 해결하기 위해 컴포넌트에서 공통으로 공유되는 상태를 추출하여 이를 전역 싱글톤으로 관리할 수 있도록 한다. 이를 통해 데이터 효율적으로 관리하며 컴포넌트 트리와 상관없이 상태에 액세스 하거나 동작을 트리거할 수 있다. 또한 상태 관리 및 특정 규칙 적용하는 로직과 상태 관련된 개념을 분리함으로써 코드의 구조와 유지 관리 기능을 향상할 수 있다.

Vuex를 적용하였을 경우

 

이 방식은 Flux, Redux, The Elm Architecture에서 영감을 받은 Vuex의 기본 아이디어이다.

Vuex의 패턴

 

Vuex의 Flux 패턴

Vuex는 Flux 패턴이 적용하여 구현되었다.(단 모든 패턴이 구현된 건 아님)
적용된 패턴의 주요 원칙 3가지는 아래와 같다.

 

원칙 #1 : Single Source of Truth (단일 데이터 소스)

컴포넌트들 간에 공유해야 할 데이터는 이를 사용하는 컴포넌트와 별도로 단일 위치(store)에 보관해야 한다.

컴포넌트는 이 단일 위치에서 공유 데이터를 읽어야 하며 충돌이나 불일치를 방지하기 위해 복사본을 자체적으로 보관해서는 안된다.

// Instantiate our Vuex store
const store = new Vuex.Store({
  
  // "State" is the application data your components
  // will subscribe to
  
  state: {     
    myValue: 0   
  }
});
// Components access state from their computed properties
const MyComponent = {   
  template: `<div>{{ myValue }}</div>`,
  computed: {
    myValue () {
      return store.state.myValue;
    }   
  } 
};

 

원칙 #2 : Data is Read-Only(데이터는 읽기만 가능)

컴포넌트는 저장소에서 데이터를 자유롭게 읽기 가능하나 저장소에 있는 데이터를 직접 변경할 수 없다.

대신 데이터 변경 시, 변경할 것이라는 정보를 저장소에 알려야 하며, 저장소는 "mutations"라는 정의된 함수를 통해 데이터를 변경한다.

데이터 변경 로직을 중앙에 둔다면 데이터에 불일치가 일어나거나 데이터에 다른 문제가 생겼을 때 멀리 볼 필요없다.
또한 어떤 컴포넌트가 예상치 못한 방식으로 데이터를 변경할 가능성을 최소화한다.

const store = new Vuex.Store({ 
  state: { 
    myValue: 0
  }, 
  mutations: { 
    increment (state, value) { 
      state.myValue += value;
    }
  } 
});
// Need to update a value?
// Wrong! Don't directly change a store value.
store.myValue += 10;
// Right! Call the appropriate mutation.
store.commit('increment', 10);

 

원리 #3 : Mutations are synchronous (Mutation은 동기적이다)

위에 두가지 원칙을 지키는 애플리케이션인 경우, 데이터를 디버깅하기 더 쉽다.

mutation의 commit을 기록하고 응답 상태가 어떻게 변경되었는지 관찰할 수 있다. (Vue Devtools에서 Vuex를 사용할 때 실제로 그렇게 디버깅 가능하다.)

만약 mutation이 비동기적이라면, commit이 언제 발생했는지 알 수 있어도 commit 안에 콜백이나 promise 같은 것이 들어간다면 추적은 불가능해진다.

 mutaion이 동기적임으로 데이터가 예측할 수 없는 이벤트 순서와 시간에 종속되지 않도록 한다.

 

Vuex는 결국 Flux 패턴을 구현하는 데 도움이 되는 라이브러리이다.

위 원칙을 적용함으로써 여러 컴포넌트에서 데이터를 공유하는 경우에 애플리케이션 데이터를 투명하고 예측 가능한 상태로 만들어 준다.

Vuex를 구현하기 위해서는 store, mutators가 포함되며 store에서 데이터를 읽는 모든 컴포넌트를 자동으로 업데이트해준다.

또한 핫 모듈 리로딩(실행 중인 애플리케이션에서 모듈 업데이트) 및 시간 이동 디버깅(버그 추적을 위한 mutation 이벤트 역추적)과 같은 개발 기능을 제공한다.

 

Vuex를 언제 사용해야 하나?

Vuex는 공유된 상태 관리를 처리하는 데 유용하나 개념에 대한 이해와 시작하는 데 비용이 많이 든다.
따라서 앱이 단순하다면 Vuex 대신 간단한 글로벌 이벤트 버스를 권장하고
중대형 SPA로 복잡한 규모의 애플리케이션을 일 경우 Vuex를 이용하여 상태 관리하는 데 유용하게 사용할 수 있을 것이다.

 

Vuex에 대한 자세한 가이드

공식 사이트 : https://vuex.vuejs.org/kr/

 

Vuex가 무엇인가요? | Vuex

Vuex가 무엇인가요? Vuex는 Vue.js 애플리케이션에 대한 상태 관리 패턴 + 라이브러리 입니다. 애플리케이션의 모든 컴포넌트에 대한 중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있습니다. 또한 Vue의 공식 devtools 확장 프로그램 과 통합되어 설정 시간이 필요 없는 디버깅 및 상태 스냅 샷 내보내기/가져오기와 같은 고급 기능을 제공합니다. "상태 관리 패턴"이란 무엇인가요? 간단한 Vue 카운터 앱부터 시작 해보

vuex.vuejs.org

 

 

참고 자료

Doit! Vue.js 입문 - 장기호 [이지스 퍼블리싱]
Anthony Gore의 포스트 : https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/
Vuex 가이드 : https://vuex.vuejs.org/kr/

'Javascript > Vue.js' 카테고리의 다른 글

[Vue] Vue 인스턴스  (0) 2019.04.14
Atom 설치하기  (0) 2019.04.14
[Vue.js] 뷰 개발자 도구 설치  (0) 2019.04.08