React에는 전역변수로 상태관리 하기 위한 라이브러리나 방법이 참 많다. Redux, MobX 그리고 요즘은 Graphql + Apollo Client로 이를 대체하기도 한다.

그럼 Vue.js에서는 어떻게 여러개의 컴포넌트에서 하나의 상태를 사용할까.

답은 Vuex 딱 한가지 라이브러리다. 정말 너~~~~~~~무 편하고 직관적이다.

Vuex는 yarn/npm을 이용해서 설치하기로 하자.

yarn add vuex
npm install vuex --save

그리고 root에서 store 디렉토리를 생성하고 modules 디렉토리를 하나 생성한다.

편리한 상태관리를 위해 필요한 기능별로 모듈을 만들어 줄 것이다.

먼저 root Store라고 할 수 있는 index.js의 코드를 작성하고 store를 생성해보자.

index.js

import Vue from 'vue';
import Vuex from 'vuex';
import todo from './modules/todo';
import user from './modules/user';

Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
        todo,
        user
    }    
})

main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

그리고 모듈을 하나씩 작성한다. 본 글에서는 가독성과 이해를 위해 간단한 user.js만 올리려고 한다.

user.js

import axios from 'axios';

export default {
    namespaced: true,
    state: {
        users: []
    },
    mutations: {    
        SET_USERS(state, users) {
            state.users = users;
        }
    },
    actions: {
        setUsers({commit}) {
            setTimeout(() => {
                axios.get('https://jsonplaceholder.typicode.com/users')
                    .then(res => commit('SET_USERS', res.data));
            }, 2000);
        }
    }
}

모듈파일을 자세히 보자.

일단 store는 state, mutations, actions, getters로 이루어져 있다.

state는 실제로 다룰 data이다. 초기값을 지정해준다.

mutations를 state를 실질적으로 변경시킬 함수이다. vuex를 사용하기 전에는 컴포넌트 별로 데이터를 push, splice등 직접 변경시켰을 것이다. 하지만 vuex를 사용한다면 꼭! mutations에서 state를 변경해야 한다.

actions는 비동기적인 처리를 다룰 함수이다. 보통은 component에서 action를 dispatch한다. 그러면 action은 정의된 비동기처리를 진행 한 후에 정해진 mutation에 commit한다. (실제 코드를 보면 {commit}이 첫번째 인자로 비구조화 할당된 것을 볼 수 있는데, context의 commit 기능만을 뺀 것이다. actions의 context는 더 공부해 보기로!)

getters는 component의 computed와 같은 기능을 한다. 여기 예시에는 들어있지 않지만, state값이 필요한게 아닌 그를 변이한 값을 갖고 싶다면 getters에서 정의한 후에 가져다 쓸 수 있다. getters로 가져온 값도 state와 마찬가지로 state값이 변동되면 rerendering 된다.

vuex 상태 가져오기

vuex에 정의된 상태를 가져올 때는 computed를 이용해야 한다.

<script>
...
    computed: {
        users(){
            return this.$store.state.user.users;
        }
    },
...
</script>

이렇게 computed에 state와 같은 이름으로 함수를 정의하고 return 받으면 일반 데이터처럼 사용할 수 있다. 그러나 값을 수정하려면 역시 actions나 mutation을 호출 해야한다.

vuex 상태 수정하기

<script>
...
    computed: {
        users(){
            return this.$store.state.user.users;
        }
    },
    methods: {
        setUser(){
            this.$store.dispatch('user/setUser');
        }
    }
</script>

vuex의 상태를 수정할 때는 methods에서 action을 dispatch해서 사용한다.

모듈이 있을 경우, 모듈명/액션명을 사용하고, 넘겨야할 인자가 있으면 두번째 인자로 넘기면 된다.

만약 action이 아닌 mutation을 바로 사용할 경우 dispatch대신 commit을 사용하면 된다.

중요한 점

  1. 모듈에선 namespaced: true값이 지정되어 있어야 한다.
  2. state 변동은 무조건 mutations에서만 한다.
  3. state나 getters를 component에서 사용할 때는 computed에서 return 받는다.
  4. mutations나 actions를 component에서 사용할 때는 methods에서 사용한다.
  5. mutation을 호출할 때는 commit()
  6. actions은 dispatch로 호출

해당 예제에는 없지만 getters를 가져다 쓰려면 methods가 아닌 computed에서 사용해야 함을 주의하자!

Leave a comment

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다