ice rabbit programming

[Vue] 렌더링에서 key의 역할 본문

Development/JavaScript

[Vue] 렌더링에서 key의 역할

판교토끼 2021. 3. 3. 03:04

리스트 렌더링 공식 가이드 : kr.vuejs.org/v2/guide/list.html#Maintaining-State

 

리스트 렌더링 — Vue.js

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

kr.vuejs.org

아래 내용은 본인이 스스로 학습한 내용으로, 실제와 다소 차이가 있을 수 있습니다. 가감없이 피드백 부탁드립니다. :)


렌더링 과정은 꽤나 무거운 작업 중 하나이다. Vue에서는 렌더링을 할 때 효율을 위해, 가상 DOM 트리를 활용하여 변경된 부분만 렌더링을 진행한다. 컴포넌트나 객체가 변경되었는지 여부를 판단하여 데이터를 로드하고 다시 렌더링하게 된다.

배열의 속성을 직접 지정해주거나, 길이를 수정하는 등 Vue가 변화를 감지하지 못하는 경우가 있고, 컴포넌트는 자체 범위가 분리되어 있어 데이터가 변경되어도 자동으로 전달되지 않는다.

이럴 때 key를 지정해주면 데이터의 변경을 감지하고 재렌더링을 진행할 수 있다. key를 가장 많이 사용하는 부분은 v-for일 것이다. 2.2.0 이상에서는 v-for에 key 값을 의무적으로 사용하도록 되어 있다. 아래와 같이 사용하면 된다.

 

<v-card 
  v-for="item in items"
  :key="item.id"
  :id="item.id"
  >
  <!-- ... -->
</v-card>

 

items에 해당하는 item들의 v-card들이 반복문으로 만들어지는 코드이다. 이름에서 알 수 있듯 key는 고유한 값을 넣어주는 편이 좋으며, id를 함께 지정해주는 편이 좋다.

그리고 상술했듯이 하위 컴포넌트에 props나 v-model로 데이터를 넘겨줄 때에도 key를 활용하면 값을 반영할 수 있다. 입력 폼에서 textfield나 select에 API 호출한 값을 초기에 넣어주는 경우와 같을 때 사용할 수 있다.

 

<my-component
  :key="myObject.id"
  v-model="myObject.name"
  >
  <!-- ... -->
</my-component>

 

이렇게 작성하면 최초에 my-component가 렌더링되고, mounted에서 API 콜을 한 결과를 myObject에 담으면 myObject.id의 변화가 감지되어, myObject.name이 데이터로 넘어가게 된다. 하위 컴포넌트 호출 시에 데이터를 반응형으로 넘기려면 key가 있어야 한다는 사실을 제대로 알지 못했고 자동으로 reactivity가 이루어진다고 생각하여 살짝 헤맸다.

끝으로 검색하다가 아래와 같은 방법을 찾아서 추가로 공유하자면

 

<my-component
  v-if="myObject.id"
  v-model="myObject.name" />

 

v-if로 컴포넌트의 렌더링 자체를 유효하지 않을 때 막는 우회(?)적인 방법이 여러 답변으로 달려 있었다. 다만 약간 동작의 차이가 있는 것이, key를 사용했을 때에는 컴포넌트 자체는 렌더링 되지만 값이 그 후에 리로딩되는 것이고, v-if로 했을 경우에는 컴포넌트의 렌더링 자체가 값이 들어올 때 이루어진다. 추가적으로 추가/수정에서 같이 사용하는 컴포넌트처럼 빈 값/기존 값을 모두 허용해야할 경우에는 처리가 복잡해질 수 있다. key를 활용하면 해결되므로 가급적 key를 사용하여 반응형 렌더링을 구현하는 편이 좋겠다.