Vuex의 마지막 부분인 Actions!
Mutations 에는 순차적인 로직들만 선언하고 Actions 에는 비 순차적 또는 비동기 처리 로직들을 선언한다.
그렇다면 왜 처리 로직의 성격에 따라 Mutations 와 Actions 로 나눠 등록을 해야할까?
따라서, setTimeout()
이나 서버와의 http 통신 처리 같이 결과를 받아올 타이밍이 예측되지 않은 로직은 Actions 에 선언한다.
Mutations 속성에는 state 값의 변화를 추적하기 어렵기 때문에 동기 처리 로직만 선언해주고,
state 호출, 변경 확인이 쉬운 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를 이용해서 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에 접근하고 변경했는지를 알 수 있게 되는 것이다.
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);
}
}
})
import {mapActions} from 'vuex';
export default {
methods: {
...mapActions([
'asyncIncrement',
'asyncDecrement'
])
},
}
📔 REFERENCE: [캡틴판교] https://joshua1988.github.io/web-development/vuejs/vuex-actions-modules/