Vue/Vuex
Vuex 핵심 컨셉(4) - 액션(actions)
고코모옹
2021. 7. 1. 18:08
- 액션(actions)
- 변이(mutation)와 유사
- 변이와 차이점
- 상태를 변이 시키는 대신 액션으로 변이에 대한 커밋을 함
- 작업에는 임의의 비동기 작업이 포함될 수 있음
- 액션 Handler는 Store 인스턴스의 동일한 메소드/프로퍼티 정보를 가지고 있는 컨텍스트(context) 객체를 받는다.
- context.commit: 변이를 커밋
- context.state: 상태에 접근
- context.getters: getters에 접근
// store/index.js
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
actions: {
// 코드를 단순화하기 위해 ES6 구조 분해 할당 사용
increment ({ commit }) {
commit('increment')
}
}
- 디스패치 액션
- 액션은 store.dispatch 메소드로 시작
store.dispatch('increment')
- 비동기 작업을 수행하기 위해 사용(mutation은 동기적이어야 함)
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
- mutation과 동일하게 payload와 객체 type을 지원
// 페이로드와 함께 디스패치
store.dispatch('incrementAsync', {
amount: 10
})
// 객체와 함께 디스패치
store.dispatch({
type: 'incrementAsync',
amount: 10
})
- 액션의 실용적인 예는 비동기 API 호출과 여러 개의 변이를 커밋하는 장비구니 결제
- 비동기 작업의 흐름을 수행하고 커밋하여 작업의 사이드이펙트(상태 변이)를 기록
actions: {
checkout ({ commit, state }, products) {
// 장바구니에 현재있는 항목을 저장하십시오.
const savedCartItems = [...state.cart.added]
// 결제 요청을 보낸 후 장바구니를 비웁니다.
commit(types.CHECKOUT_REQUEST)
// 상점 API는 성공 콜백 및 실패 콜백을 받습니다.
shop.buyProducts(
products,
// 요청 성공 핸들러
() => commit(types.CHECKOUT_SUCCESS),
// 요청 실패 핸들러
() => commit(types.CHECKOUT_FAILURE, savedCartItems)
)
}
}
- 액션 구성하기
- 액션은 비동기 처리가 가능하다. 그러면 액션이 언제 완료되는지 어떻게 알 수 있을까? 복잡한 비동기 흐름을 처기하기 위해 어떻게 여러 작업을 함께 구성해야 할까?
- 가장 먼저 알아야 할 점은 store.dispatch가 트리거 된 액션 Handler에 의해 반환된 Promise를 처리할 수 있으며 Promise를 반환한다는 것
// store.js
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
// Vue component에서 호출
store.dispatch('actionA').then(() => {
// ...
})
- 액션 안에 또 다른 액션 사용 가능
actions: {
// ...
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
}
- async/await 사용
// getData() 및 getOtherData()가 Promise를 반환한다고 가정합니다.
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // actionA가 끝나기를 기다립니다.
commit('gotOtherData', await getOtherData())
}
}
[ 참고자료 ]
https://next.vuex.vuejs.org/guide/actions.html#composing-actions
Actions | Vuex
Actions Actions are similar to mutations, the differences being that: Instead of mutating the state, actions commit mutations.Actions can contain arbitrary asynchronous operations. Let's register a simple action: const store = createStore({ state: { count:
next.vuex.vuejs.org