Vue Vuex 변이

YEZI🎐·2022년 12월 13일
0

Vue

목록 보기
42/45

변이(mutations)

Vuex 저장소에서 실제로 상태를 변경하는 유일한 방법은 변이(mutations)하는 것이다.
Vuex mutations은 이벤트와 매우 유사하다.
각 mutations에는 타입 문자열 핸들러가 있고 핸들러 함수는 실제 상태 수정을 하는 곳이며, 첫 번째 전달인자로 상태를 받는다.

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 상태 변이
      state.count++
    }
  }
})

mutations 핸들러를 직접 호출 할 수는 없다.
위 예제에서 타입이 increment인 mutations이 발생하면이 핸들러를 호출한다.
mutations 핸들러를 호출하려면 해당 타입과 함께 store.commit을 호출해야 한다.

store.commit('increment')

payload를 가진 commit

mutations에 대해 payload 라고하는 store.commit에 추가 전달인자를 사용 할 수 있다.

// ...
mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

payload는 객체로 전달될 수 도 있다.

// ...
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit('increment', {
  amount: 10
})

객체 스타일 commit

mutations을 commit하는 또 다른 방법은 type 속성을 가진 객체를 직접 사용하는 것이다.

store.commit({
  type: 'increment',
  amount: 10
})

객체 스타일 commit을 사용할 때 전체 객체는 mutations 핸들러에 페이로드로 전달되므로 핸들러는 동일하게 유지된다.

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

Vue의 반응성 규칙을 따르는 mutations

Vuex 저장소의 상태는 Vue에 의해 반응하므로, 상태를 변경하면 상태를 관찰하는 Vue 컴포넌트가 자동으로 업데이트된다.
이것은 Vuex mutations이 일반 Vue로 작업 할 때 동일한 반응성에 대한 경고를 받을 수 있음을 의미한다.

  1. 원하는 모든 필드에 앞서 저장소를 초기화하는 것이 좋다.
  2. 객체에 새 속성을 추가할 때 다음 중 하나를 수행해야 한다.
    • Vue.set(obj, 'newProp', 123)을 사용하거나,
    • 객체를 새로운 것으로 교체해야 한다. (ex. 객체 확산 문법 사용)
state.obj = { ...state.obj, newProp: 123 }

mutations 타입에 상수 사용

다양한 Flux 구현에서 mutations 유형에 상수를 사용하는 것은 일반인 패턴이다.
상수를 사용하는 것은 개발자가 많은 대규모 프로젝트에서 유용할 수 있지만,
이는 완전한 선택 사항이다.

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
  state: { ... },
  mutations: {
    // ES2015에서 계산 된 프로퍼티 이름 기능을 사용하여
    // 상수를 함수 이름으로 사용할 수 있음
    [SOME_MUTATION] (state) {
      // 변이 상태
    }
  }
})

컴포넌트 안에서 mutations commit

this.$store.commit('xxx')를 사용하여 컴포넌트에서 mutations를 수행하거나 컴포넌트 메소드를 store.commit 호출에 매핑하는 mapMutations 헬퍼를 사용할 수 있다.

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment' // this.increment()를 this.$store.commit('increment')에 매핑합니다.
    ]),
    ...mapMutations({
      add: 'increment' // this.add()를 this.$store.commit('increment')에 매핑합니다.
    })
  }
}

mutations은 무조건 동기적

기억 해야할 한 가지 중요한 규칙은 mutations 핸들러 함수는 동기적이어야 한다는 것이다.

mutations: {
  someMutation (state) {
    api.callAsyncMethod(() => {
      state.count++
    })
  }
}

기록된 모든 mutations에 대해 devtool은 상태의 이전∙이후 스냅샷을 캡처해야 한다.
그러나 위 mutations 내의 비동기 콜백은 불가능하다.
mutations이 commit 되었을 때 콜백은 아직 호출되지 않고, 콜백이 실제로 호출 될 시기를 devtool이 알 수 있는 방법이 없다.
콜백에서 수행 된 모든 상태 mutations은 본질적으로 추적 할 수 없다.
이를 해결하기 위해서는 액션을 사용해야 한다.

profile
까먹지마도토도토잠보🐘

0개의 댓글