개발 일기

Vuex - action ? 본문

Client/vue

Vuex - action ?

이건욱

Action ?

2020/09/15 - [Client/vue] - Vuex ?

액션은 위에서 올렸던 변이와 유사합니다. 몇가지 다른 점을 나열해 보도록 하겠습니다.

 

- 상태를 변이시키는게 아니라 액션으로 변이에 대한 커밋을 합니다.

- 작업에 비동기 작업이 가능해집니다.

actions: {
    incrementAsync(context) {
        setTimeout(() => {
            context.commit('increment')
        } , 1000)
    },
    decrementAsync(context) {
        setTimeout(() => {
            context.commit('decrement')
        } , 1000)
    }
  },

위와 같이 context을 통해서 commit을 하거나 혹은 context.state , context.getters을 통해 상태와 getter에 접근을 할수가 있습니다.

 

실제로는 코드를 단순하기 사용하기 위해서 아래와같이 전달인자 분해를 많이 사용을 합니다.

actions: {
    incrementAsync({commit}) {
        setTimeout(() => {
            commit('increment')
        } , 1000)
    },
    decrementAsync({commit}) {
        setTimeout(() => {
            commit('decrement')
        } , 1000)
    }
  },

디스패치 액션

액션은 store.dispatch 메소드를 사용하여 구성할수가 있습니다.

methods: {
    increment: function () {
      this.$store.dispatch('incrementAsync')
    },
    decrement: function () {
      this.$store.dispatch('decrementAsync')
    }
  }

위와같이 commit을 직접 호출을 안하고 하는 이유는 비동기에서 작업이 가능하도록 작성하는것 입니다.

 

페이로드를 같이 전달하기 위해서는 다음과 같이 두가지 방법이 있습니다.

// 페이로드와 함께 디스패치
store.dispatch('incrementAsync', {
  amount: 10
})

// 객체와 함께 디스패치
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

mapActions

액션도 마찬가지로 헬퍼가 존재합니다.

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment' // this.increment()을 this.$store.dispatch('increment')에 매핑

      // mapActions는 페이로드를 지원합니다.
      'incrementBy' // this.incrementBy(amount)를 this.$store.dispatch('incrementBy', amount)에 매핑
    ]),
    ...mapActions({
      add: 'increment' // this.add()을 this.$store.dispatch('increment')에 매핑
    })
  }
}

액션 구성

액션은 비동기로 많이 이루어져있습니다.

따라서 복잡한 비동기에서 여러 다른 작업과 동시에 하고 싶을 때 store.dispatch 액션 핸들러에서 반환된 Promise을 사용할수가 있습니다.

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

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())
  }
}

 

'Client > vue' 카테고리의 다른 글

vuex - module  (0) 2020.09.15
Vuex ?  (0) 2020.09.15
Vue-router  (0) 2020.09.15
클래스와 스타일 바인딩  (0) 2020.09.14
템플릿 문법  (0) 2020.09.01
Comments