Vuex4 (2) State, getters, mutations, actions

김다운·2022년 2월 11일
0

vuex

목록 보기
2/4
post-thumbnail

Vuex 기본 구조

출처,참고
Vuex 시작하기1 - Vuex와 State

상태 관리 패턴

State 는 컴포넌트 간 공유할 data를 담는 그릇이다. view(template) 영역의 표시된 데이터가 actions(methods) 을 통해 State를 변형 시킨다.

<template>
	<!--view-->
	<div>{{count}}</div>
</template>

....
// state
data(){
	return{
    	count:0
    }
},
//action
methods:{
	addCount(){
    	this.count++;
    }	
}
....

State

예시 코드

State 등록

//store/index.js or store/index.ts

import { createStore } from "vuex";

export default createStore({
  state: {
    loginData: {
      count: 0,
    }
  },
});

state에 정의된 속성은 기존 vue의 코드중 data의 역할을 한다. State는 컴포넌트 간 공유할 data역할을 한다.

State 접근

<div>
	<h1>Counter: {{$store.state.counter}}</h1>
    <button @click="$store.state.counter++">+</button>
    <button @click="$store.state.counter--">-</button>
</div>

getters

예시코드
중앙 데이터 관리식 구조의 문제점 중 하나는 각 컴포넌트에서 vuex 의 데이터를 접근할 때 중복된 코드를 반복호출 하게 되는 것이다.

// App.vue
computed: {
  doubleCounter() {
    return this.$store.state.counter * 2;
  }
},

// Child.vue
computed: {
  doubleCounter() {
    return this.$store.state.counter * 2;
  }
},

동일한 State를 동일하게 가공해서 사용하는 경우 각 컴포넌트 중복되어 함수가 작성되어야한다.
각 컴포넌트에서 해당 작업을 수행하는 것이 아니라 vuex에서 수행하도록 하여 성능과 가독성에서 이점을 가질 수 있다.

// store/index.js
getters:{
	doubleCounter(state){
    	return state.counter * 2;
    }
}
<h1>doubleCounter: {{$store.getters.doubleCounter}}</h1>

mapGetters

vuex에 내장된 helper 함수, mapGetters 로 getters 에 작성된 코드를 직관적으로 가져올 수 있다.

import {mapGetters} from 'vuex'
....
  computed: {
    ...mapGetters(["doubleCounter"]),
  },
....
<h1>doubleCounter: {{doubleCounter}}</h1>

mutation

vuex 의 state 값을 동기적으로 변경하는 로직을 의미한다. 위에 까지 counter를 변경할 때
직접 state에 접근하여 변경하였지만 이건 안티패턴으로 vue의 reactivitiy 체계와 상태관리 패턴에 맞지 않는 방식이다. 여러 개의 컴포넌트에서 같은 state 값을 동시에 제어하게 되면 state값이 어느 컴포넌트에서 호출해서 변경된건지 추적하기 어렵기 때문이다.
mutation은 상태 변화를 명시적으로 수행함으로써 테스팅, 디버깅, Vue의 Reactive 성질을 준수하게 된다

예시코드

Mutations 등록

// store/index.js

mutations: {
	addCounter(state, payload) {
      state.counter++
	},
},
<button @click="addCounter">+</button>
...
import store from './store'
...
methods: {
  addCounter() {
    store.commit("addCounter");
  },
},

mutations 에 인자 넘기기

state를 변경하는데 특정 값을 넘길경우 commit에 두번째 값(payload)를 추가한다.

//App.vue
store.commit("addCounter",{value:10});

//store/index.js
mutations: {
  // payload 가 { value : 10 } 일 경우
  addCounter(state, payload) {
    state.counter = payload.value;
  }
}

mapMutations

mapGetters 와 마찬가지로 Vuex 에 내장된 mapMutations 를 이용하여 코드 가독성을 높일 수 있다.

action

예제코드
Mutations 에는 순차적인 로직만 선언하고 Actions 에는 비 순차적 또는 비동기 처리 로직들로 선언한다.
Mutations 의 역할 자체가 State 관리에 주안점을 두고 있다. 상태관리 자체가 한 데이터에 대해 여러 개의 컴포넌트가 관여하는 것을 효율적으로 관리하기 위함인데 Mutations 에 비동기 처리 로직들이 포함되면 같은 값에 대해 여러 개의 컴포넌트에서 변경을 요청했을 때 변경 순서를 파악하기 어렵다.
setTimeOut()이나 서버와의 http 통신 처리 같이 결과를 받아올 타이밍이 예측되지 않는 로직은 Actions 에 선언한다.

mutation 과의 차이

  • mutations 는 동기적인 로직을 정의
  • Action 은 비동기적 로직을 정의

Actions 등록

// store/index.js
  actions: {
    ADDCOUNT({ commit }) {
      commit('addCounter')
    },
    ADDCOUNTPALOAD({ commit},payload) {
      commit('addCounter',{value:payload})
    }
  },
비동기 처리 예

HTTP 요청이나 setTimeOut과 같은 비동기 처리 로직들은 actions에서 사용한다.

actions:{
	getApiData({commit}){
      axios.get('APISERVER').then((res)=>{
      	commit('mutationName',res.data);
      })    
    }
}

Actions 사용

methods:{
	addCounter() {
    	store.dispatch('ADDCOUNT');
  	},
    addCounterPayload(){
    	store.dispatch('ADDCOUNTPALOAD',3);
    }
}
profile
열려 있는 FE 개발자

0개의 댓글