Vue 3 에서 Vuex를 Store 역할로 사용할 때 헷갈리는 부분이 Mutation과 Action의 차이였다.
우선, 가장 큰 차이점은 비동기 연산을 하느냐 마느냐 하는 것이다.
Vuex Store는 크게 4가지 속성이 있다.
state, getters, mutations, 그리고 actions.
state는 말 그대로 현재 상태를 담고 있는 변수이다.
getters도 말 그대로 state의 값을 얻어오는 역할이다.
mutations은 state를 변경할 수 있게 해주는 유일한 녀석이다.
'변이' 라는 뜻 그대로 state의 상태를 변화시키는 것이다.
이쯤이면 필요한 건 다 있는 것 같은데 actions라는 속성이 하나 더 있다.
actions는 state와 관련한 비동기 연산을 담당한다.
그리고 비동기 작업이 끝나면 mutations를 호출하여 state를 변경한다.
왜 굳이? 그냥 mutations에서 비동기를 처리하고 그 다음에 state를 변경까지 해버리면 편하지 않아?! 라는 의문이 생긴다.
그 이유인즉슨,
devtools 등의 디버깅 툴로 state값을 체크하고자 할 때 비동기 연산이 있다면
그 작업이 끝나기도 전에 devtools는 state값을 먼저 체크해서 개발자에게 알려주게 된다.
개발자는 작업을 시작하기 전과 후의 state 차이를 보고 싶어하지만
devtools는 비동기 작업이 끝났는지 여부에 상관없이 그냥 자기 할일(state 값 확인)만 하고 디버깅을 종료한다.
즉, (state 변경을 담당하는) mutations가 비동기 작업을 하면 정확한 state 값을 얻기가 어렵다.
그래서 비동기 작업은 먼저 actions에서 다 처리하고 마지막 state를 바꾸는 작업만 mutations에서 진행한다.
물론, mutations가 state를 바꾸는 작업은 동기적으로 진행된다.
Composition API에서 mutations와 actions를 호출할 때도 이 둘을 구분하여 호출한다.
mutations를 호출할 경우 commit() 함수를,
actions를 호출할 경우 dispatch() 함수를 사용한다.
(그리고 노파심에 하는 말이지만.. Store가 namespace를 사용하고 있는 상태라면 commit(), dispatch() 함수를 사용할 때 namespace를 같이 넣어 주어야 한다. 'CLOSE_MODAL'이 아니라 'common/CLOSE_MODAL' 이다..!!)
/* add-modal.js */
/* Vue Composition API */
import { useStore } from 'vuex'
const store = useStore()
function close() {
store.commit('common/CLOSE_MODAL'); /* Mutations를 호출할 땐 commit() 사용 */
}
function submit(data) {
store.dispatch('common/SUBMIT_DATA', data); /* Actions를 호출할 땐 dispatch() 사용 */
}
/* common.js */
import { createNamespacedHelpers } from 'vuex';
export const { mapState, mapMutations, mapActions } = createNamespacedHelpers('common');
export default {
namespaced: true,
state: () => ({
SHOW_MODAL: false,
DATA: []
}),
getters: {},
mutations: {
CLOSE_MODAL(state) {
state.SHOW_MODAL = false;
},
ADD_DATA(state, newData){
state.DATA.push(newData);
}
},
actions: {
SUBMIT_DATA({ commit }, param) {
const response = await axios.post('/data', {
name: param.name
});
commit('ADD_DATA', response.data);
}
}
}
* 참고
Mutations> https://beomy.tistory.com/86
Actions> https://beomy.tistory.com/87
'Development Experience > Web' 카테고리의 다른 글
Vue.js 에서 Function Props는 안티패턴? (0) | 2022.10.27 |
---|---|
콘솔에 객체 내부 데이터 출력하기 (feat. Vue, React, Javascript) (0) | 2022.09.26 |
Vue 독립적인 Component 간의 데이터 통신 (feat. vuex store) (2) | 2022.09.21 |
여러 HTML 태그를 겹쳐서(overlay) 사용하고 싶을 때 (0) | 2022.09.16 |
Vue에서 글자 옆에 사각형을 그릴 때.. (0) | 2022.08.22 |