본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section15] 223. 지역 모듈 상태 이해하기

메인 저장소에 모듈이 결합될때, 메인 저장소의 다른 요소들과 같은 레벨로 결합된다.

이런 동작은 바꿀 수 있다.

사실 이미 바뀐 곳이 있다.

 

 

mutations에 increase 안에 console.log(state)를 찍어보자.

increase 변형이 아닌, counterModule 안에 increase 변형 안에 있다.

'Add 10'을 클릭해보자.

<template>
 <!--생략-->
    <button @click="addOne">Add 10</button>
 <!--생략-->
</template>

<script>
export default {
  methods: {
    addOne() {
       this.$store.dispatch({
         type: 'increase',
         value: 10,
       });
    },
  },
};
</script>

state에 대한 로그를 살펴보면, 흥미로운 점을 볼 수있다.

counter는 볼 수 있는데, 'isLoggedIn'상태는 없다.

 

그렇다면, 모든 게 한 저장소에 결합된다고 했는데 왜 isLoggedIn은 counterModule의 state에 보이지 않을까?

모듈 내의 state는 모듈 내의 local 상태로 간주되기 때문이다.

 

mutations, actions, getters는 global이라 메인 저장소에서 액세스할 수 있지만,

state는 모듈의 지역 상태이므로, 모듈 내에 state는 해당 모듈에만 적용된다.

즉, getter에서 isLoggedIn 상태를 받지 못한다.

 

 

counterModule에 새 getter객체로 'testAuth'를 추가하고,

state.isLoggedIn을 반환하면 제대로 작동하지 않는다.

UserAuth.vue 컴포넌트에 computed 프로퍼티에 isTestAuth를 추가하고, 새로 추가한 getter인 testAuth를 반환해보자.

→ 출력해보면, 작동하지 않는다.

왜냐하면 counterModule의 getters의 state에서는 global state인 isLoggiedIn을 찾지 못하므로.

이 getter는 counterModule에 있고, state는 local에 적용되기 때문에 모듈에 속한 state만 액세스할 수 있다.

// main.js

// counterModule
const counterModule = {
  state() {
    return {
      counter: 0,
    };
  },
  mutations: {
    increment(state) {
      state.counter = state.counter + 2;
    },
    increase(state, payload) {
      console.log('state', state);
      state.counter = state.counter + payload.value;
    },
  },
  actions: {
    increment(context) {
      setTimeout(function () {
        context.commit('increment');
      }, 2000);
    },
    increase(context, payload) {
      console.log('context', context);
      context.commit('increase', payload);
    },
  },
  getters: {
    testAuth(state, getters, rootState, rootGetters) {
      return state.isLoggedIn; //state에서 isLoggedIn을 못찾는다. state는 모듈의 지역상태
    },
    finalCounter(state) {
      return state.counter * 3;
    },
    normalizedCounter(state) {
      const finalCounter = state.counter * 3;
      if (finalCounter < 0) {
        return 0;
      }
      if (finalCounter > 100) {
        return 100;
      }
      return finalCounter;
    },
  },
};

const store = createStore({
  modules: {
    numbers: counterModule,
  },
  state() {
    return {
      isLoggedIn: false,
    };
  },
  mutations: {
    setAuth(state, payload) {
      state.isLoggedIn = payload.isAuth;
    },
  },
  actions: {
    login(context) {
      context.commit('setAuth', { isAuth: true });
    },
    logout(context) {
      context.commit('setAuth', { isAuth: false });
    },
  },
  getters: {
    userIsAuthenticated(state) {
      return state.isLoggedIn;
    },
  },
});

 

action, mutation도 마찬가지이다.

예를 들어, actions의 context에서 state에 액세스할 수 있다고 배웠다.

이때도 해당 모듈에 대한 상태만 액세스할 수 있다.

 

사실 해결하고자 하면 방법은 있다.

모듈 내의 getter에서 전처럼 state와 getters만 받는 것이 아니라 rootState 및 rootGetters도 받으면 된다.

actions의 context 객체에서 비슷한 프로퍼티를 본 적이 있다.

이렇게 하면 모듈 내의 state 뿐만 아니라 메인 state에도 액세스하고, 전체 store의 메인 getter에 액세스할 수 있다.

특정 모듈에 대한 state만이 아니라.

 

필요한 경우, 모듈에 속하지 않는 상태에 접근할 수 있는 대비책이다.

하지만 보통은 모듈 내에서 모듈에 속한 상태만 다루게 된다.

따라서 자주 사용할 일은 없지만, 필요한 경우 이 방법을 사용하면 된다.

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.