[Vue.js] Vuex 시작 (3) - Actions

dl_edge·2021년 9월 30일
2

Vue.js

목록 보기
4/5

Vuex의 마지막 부분인 Actions!

Actions 란?

Mutations 에는 순차적인 로직들만 선언하고 Actions 에는 비 순차적 또는 비동기 처리 로직들을 선언한다.

그렇다면 왜 처리 로직의 성격에 따라 Mutations 와 Actions 로 나눠 등록을 해야할까?


  • Mutations 의 역할은 State 관리에 초점을 두고 있다.
  • => 한 데이터에 대해 여러 개의 컴포넌트가 접근할 때, 어느 컴포넌트에서 접근했는지를 알기 위해 사용한다고 배웠다.
  • 상태 관리 자체가 한 데이터에 대해 여러 개의 컴포넌트가 관여하는 것을 효율적으로 관리하기 위함인데 Mutations 에 비동기 처리 로직들이 포함되면 같은 값에 대해 여러 개의 컴포넌트에서 변경을 요청했을 때, 그 변경 순서 파악이 어렵기 때문이다.
이러한 문제를 방지하기 위해 비동기 처리 로직은 Actions 에, 동기 처리 로직은 Mutations 에 나눠 구현한다.

따라서, setTimeout() 이나 서버와의 http 통신 처리 같이 결과를 받아올 타이밍이 예측되지 않은 로직은 Actions 에 선언한다.


:pushpin:Tip! 동기 처리(Mutations) vs. 비동기 처리(Actions)

Mutations 속성에는 state 값의 변화를 추적하기 어렵기 때문에 동기 처리 로직만 선언해주고,

state 호출, 변경 확인이 쉬운 Actions 에는 비동기 처리 로직을 선언해준다.


Actions 등록

Vuex에 Actions를 등록하는 방법은 State나 Mutations, Getters 와 유사하다.

// store.js
export const store = new Vuex.Store({
  // ...
  mutations: {
    addCounter: function (state, payload) {
      return state.counter++;
    }
  },
  actions: {
    addCounter: function (context) {
      // commit 의 대상인 addCounter 는 mutations 의 메서드를 의미한다.
      return context.commit('addCounter');
    }
  }
});

상태가 변화하는 걸 추적하기 위해 actions는 결국 mutations의 메서드를 호출(commit)하는 구조가 된다.

// store.js
export const store = new Vuex.Store({
  actions: {
    getServerData: function (context) {
      return axios.get("sample.json").then(function() {
        // ...
      });
    },
    delayFewMinutes: function (context) {
      return setTimeout(function () {
        commit('addCounter');
      }, 1000);
    }
  }
});

위처럼 HTTP get 요청이나 setTimeout 과 같은 비동기 처리 로직들은 actions 에 선언해준다.


Actions 사용

Actions를 이용해서 counter를 하나씩 늘려보자.

Actions를 호출할 때는 dispatch() 를 이용한다. (Mutations는 commit() 사용)

// App.vue
methods: {
  // Mutations 를 이용할 때
  addCounter() {
    this.$store.commit('addCounter');
  }
  // Actions 를 이용할 때
  addCounter() {
    this.$store.dispatch('addCounter');
  }
},

전체 구조도에서 dispatch 의 동작을 보면,

  • App.vue에서 addCounter 이벤트가 발생하고, Vuex의 Actions에 dispatch를 한다.

  • dispatch를 받은 Actions는 Mutations 에 commit 을 하고,

  • Mutations 에 정의되어 있는 메서드가 호출되어 Vuex의 State를 변경시킨다.

위와 같은 흐름으로 상태 관리를 하게 되면, 어느 컴포넌트에서 어떤 순서로 State에 접근하고 변경했는지를 알 수 있게 되는 것이다.


Actions 에 인자 값 넘기기

Mutations와 유사하다.

<!-- by 와 duration 등의 여러 인자 값을 넘길 경우, 객체안에 key - value 형태로 여러 값을 넘길 수 있다 -->
<button @click="asyncIncrement({ by: 50, duration: 500 })">Increment</button>
export const store = new Vuex.Store({
  actions: {
    // payload 는 일반적으로 사용하는 인자 명
    asyncIncrement: function (context, payload) {
      return setTimeout(function () {
        context.commit('increment', payload.by);
      }, payload.duration);
    }
  }
})

mapActions

import {mapActions} from 'vuex';

export default {
  methods: {
    ...mapActions([
      'asyncIncrement',
      'asyncDecrement'
    ])
  },
}

📔 REFERENCE: [캡틴판교] https://joshua1988.github.io/web-development/vuejs/vuex-actions-modules/

profile
TIL (Today I Learned!) 전공 까먹기 싫어서 정리하는 중🎁

0개의 댓글