개발자 9Diin의 개발일기

Vue.js 데이터 변경 라이프사이클 훅으로 해결 본문

2021-2023

Vue.js 데이터 변경 라이프사이클 훅으로 해결

9Diin 2022. 5. 16. 17:07
반응형

📌 Prologue

나는 Vue.js라는 자바스크립트를 활용한 지 이제 한 달 남짓이다. Vue.js (이하 Vue)를 사용하면서 느꼈던 것은 Vue라는 언어를 만들어 낸 창시자는 정말 너무나도 대단한 사람처럼 느껴졌고, 프런트엔드 개발자라면 당연히 자바스크립트라는 언어를 잘 다룰 줄 알아야 하지만, 보다 멋지고 간편한 그리고 효율성 좋은 Vue를 활용하는데 자바스크립트의 기초만 있는 사람이어도 어느 정도 활용이 가능하는 게 내겐 너무나도 큰 장점으로 와닿았다.

 

그래서일까? 나는 Vue가 너무 좋고, 더 깊게 잘 배우고 싶다. 아무튼, 본격적인 Vue.js의 Lifecycle Hooks에 대해 살펴보도록 하자.

📌 Lifecycle Hooks

내가 근 한 달 가까운 시간 동안 그중의 반은 회사 적응 기간이었지만 Vue라는 언어에 대해 아주 조금 살펴보면서, 가장 공부하기 싫었던 부분이 바로 이 부분이었다. 바로 Lifecycle Hooks.

그냥 작동하게 만들면 되는 걸, 왜 생태계처럼 얽히고설킨 사이클(Cycle)이 있을까?

그 이유를 살펴보기 위해 Vue.js 공식문서를 한 번 살펴보았다.

✅ Vue.js 공식문서 - Lifecycle Hooks는 무엇인가?

 

API — Vue.js

Vue.js - 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

✅ 옵션 / 라이프사이클 훅 (공식문서 내용)

모든 라이프사이클 훅은 자동으로 this 콘텍스트를 인스턴스에 바인딩하므로 데이터, 계산된 속성 및 메서드에 접근할 수 있다. 즉, 화살표 함수를 사용하여 라이프사이클 메서드를 정의하면 안 된다.

 

created: ( ) => this.fetchTodos( ) 이런 식으로 작성하면 안 된다고 한다. 그 이유는 화살표 함수가 부모 콘텍스트를 바인딩하기 때문에 this는 예사대로 Vue 인스턴스가 아니며 this.fetchTodos는 정의되지 않는다고 한다. 무슨 말인지 모르겠다. 너무 어렵다. 😭😭

 

모든 컴포넌트는 생성될 때 초기화 단계를 거치는데, 예를 들어, 데이터의 변경사항 감시를 위한 설정, 템플릿 컴파일, 인스턴스를 DOM에 마운트하고, 데이터가 변경되면 DOM을 업데이트해야 한다.

 

어쩌면 당연한 말인데, 나는 현재 Vue로 토이 프로젝트를 진행하면서, 데이터가 변경되면 DOM을 업데이트 해아 한다는 것을 이 포스팅을 작성하는 오늘에서야 알게 되어 활용하여 꾸역꾸역 Issue 없이 해결했다.

📌 라이프사이클 훅에서 문제를 찾다.

위 사진은 내가 현재 Vue.js 와 OpenWeatherMap API, KakaoMap API를 활용하여 만들어 본 예제이다. 카카오 맵 위에 찍힌 마커를 클릭하면, 클릭된 마커의 좌표가 날씨 api로 동적으로 넘어가야 하는데 이곳에서 여러 가지 issue가 있었다. 그래서 공부하면서 생각했던 건, 아! 코드에 이상이 없다면, 내가 짠 코드의 로직에 이상이 없다고 판단이 되면 해당 언어의 라이프사이클 훅을 한 번 생각해보길 바란다. 나 역시 이곳에서 문제를 해결할 수 있었다.

 

그러나 어떤 외부적인 요인으로 인해 전달받는 데이터를 변경해야 할 상황이라면 훗날 알게 되었지만,

라이프사이클 훅 보다 Computed 혹은 Watch 속성을 활용하여 캐싱을 하던지, 변경된 데이터만 감지하여 그 부분만 변경시켜주는 등의 방식으로 해결하는 것이 더 효율적이라 생각이 든다.

✅ updated

  • 타입 : Function
  • 데이터가 변경되어 가상 DOM이 재 랜더링 되고 패치되면 호출된다.
    이 훅이 호출되면 일리 먼트 DOM이 업데이트된 상태가 되어 이 훅에서 DOM 종속적인 연산을 할 수 있습니다. 그러나 대부분의 경우 무한루프가 발생할 수 있으므로 훅에서 상태를 변경하면 안 됩니다. 상태 변화에 반응하기 위해서 계산된 속성 또는 감시자를 사용하는 것이 더 좋습니다.
  • updated는 모든 자식 컴포넌트가 재-렌더링 된 상태를 보장하지 않습니다. updated 내부에서 vm.$nextTick를 사용하면 전체가 업데이트된 상태를 보장합니다.
updated: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been re-rendered
  })
}

 

나는 카카오 맵 마커 클릭 시 넘어오는 데이터가 동적으로 변경되어야 하기 때문에 updated 라이프사이클 훅을 활용하여 문제를 해결했다. 그러나 위에서도 설명했듯이 updated 라이프사이클 훅을 활용하여 페이지를 업로드하게 된다면, 전체적으로 한 번 재로드를 하기 때문일까? 깜박거리는 현상이 있었다. 

 

그렇기에 위 설명처럼 상태 변화에 반응하기 위해서 계산된 속성 또는 감시자를 사용하는 것이 더 좋다. 즉 Computed or Watch를 사용하는 편이 유용하다 할 수 있다.

 

https://www.youtube.com/watch?v=PhSF00HKpj0 

 

반응형