익명의 개발노트

[vue.js] vuex 상태변화시 리랜더링 안되는 현상(강제 리랜더링) 본문

코딩일기/TIL

[vue.js] vuex 상태변화시 리랜더링 안되는 현상(강제 리랜더링)

캡틴.JS 2020. 1. 29. 19:37
반응형

가운데가 부모컴포넌트, 버튼과 input창은 각각의 자식컴포넌트이다.

 

이메일 형식을 입력하면 버튼이 파란색으로 활성화 되고, 수정하여 이메일 형식이 아니면 버튼이 회색으로 바뀌는 기능

구현 중 리랜더링이 안되는 현상에 대해 적어본다.

우선 input 값을 입력하면, 해당 입력값은 Vuex 로 저장이 되며, 부모 컴포넌트에서 Vuex에 있는 값을 불러와서 사용한다.

버튼이 파란색까지는 변하는데, 그 후 Input 창의 내용을 수정하면 버튼이 회색으로 돌아오지 않았다.

Vuex까지는 데이터가 들어가는데, 부모컴포넌트에서 리랜더링이 되지 않았다.

라이프싸이클도 확인해 본 결과, 파란색 버튼이 된 경우까지만 작동하고,

input창의 내용을 수정하면 라이프싸이클도 작동하지 않았다.

콘솔에는 nextTick 에러만 뜨고...

우선 Vuex내에 state 값을 객체형식으로 구현했는데, 이게 문제가 된 듯 싶어서,

Vue에서는 상태가 객체인 경우 변화를 인지하지 못할 수도 있기에 

Vue.set()을 이용하여 아래와 같이 상태관리 코드를 변경해주었다.

//vuex 일부

state: {
    customButton: {
      innerValue: '',
      buttonClassName:'gray-btn',
    }
  },
  mutations: {
    SET_CHANGE_INNER_VALUE(state, innerValue: string){
      state.customButton.innerValue = innerValue;
    },
    SET_CHANGE_BUTTON_COLOR(state, buttonClassName: string){
      state.customButton = { ...state.customButton, buttonClassName: buttonClassName };
    },   
  },

Vuex를 고쳤는데, 똑같이 부모컴포넌트에서 리랜더링이 되지 않았다.

강제로 리랜더링하는 방법을 찾는 도중, :key를 이용한 리랜더링 진행해서 해결하였다.

//부모컴포넌트

<template>
  <div class="wrapper-email-btn">
    <!-- 헤더 넣어야 할 곳 -->
    <form @submit.prevent="onSubmit"> <!--버튼 이벤트 prevent해주어야함. -->
      <h1 class="title-text">이메일 주소를 알려주세요.</h1>
      <div class="wrapper-input">
       <custom-input inputType="email"></custom-input>
      </div>
      <div class="wrapper-btn">
        <custom-button buttonName="다음" 
        :buttonClassName="this.$store.getters.getButtonColor" 
        ></custom-button>
      </div>
    </form>
  </div>
</template>

위의 코드로는 리랜더링이 되지 않았는데, 사용하고자 하는 곳에 :key 프롭을 이용하여, 해결

<template>
  <div class="wrapper-email-btn">
    <!-- 헤더 넣어야 할 곳 -->
    <form @submit.prevent="onSubmit"> <!--버튼 이벤트 prevent해주어야함. -->
      <h1 class="title-text">이메일 주소를 알려주세요.</h1>
      <div class="wrapper-input">
       <custom-input inputType="email"></custom-input>
      </div>
      <div class="wrapper-btn">
        <custom-button buttonName="다음" :buttonClassName="this.$store.getters.getButtonColor" 
        :key="this.$store.getters.getButtonColor"
        ></custom-button>
      </div>
    </form>
  </div>
</template>

 

강제랜더링 방법을 보니

1.라우터를 이용한 방법 : this.$router.go(0)

2. v-if를 이용한 방법 : 위의 내용에서는 v-if가 먹히질 않았다.

3. vm.$set("x",0), vm.$delete("x") : x는 존재하지 않는 변수

여러가지 방법 중에 가장 효율적인 것은 :key 라고 한다.

참고자료 : https://www.it-swarm.dev/ko/javascript/vuejs%EB%A5%BC-%EB%8B%A4%EC%8B%9C%EB%A1%9C%EB%93%9C%ED%95%98%EA%B1%B0%EB%82%98-%EB%8B%A4%EC%8B%9C-%EB%A0%8C%EB%8D%94%EB%A7%81-%ED%95%A0-%EC%88%98-%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C/1054188483/

 

 

반응형
Comments