늘 겸손하게

React - key props를 사용하는 이유 본문

Programming/React

React - key props를 사용하는 이유

besforyou999 2022. 7. 23. 20:57

map 메소드를 이용해 배열의 요소들을 출력할때 key props를 요구하는 경우가 많다.
 
key props를 추가하지 않으면 콘솔에 오류가 출력되는것을 볼 수 있다.
 
왜 key를 props로 요구하는걸까?
 
해답은 공식문서에 있었다

 

1. 배열 원소의 고유성 확보

 
Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다.
 
key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.
 

1
2
3
4
5
6
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);
cs

 
 
Key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것.
 
대부분의 경우 데이터의 ID를 key로 사용합니다.
 

요약 => 배열의 원소에 고유성을 부여하여 원소를 수정, 제거, 추가를 용이하게 하기 위해서 Key를 요구합니다.
 

2. 자식에 대한 재귀적 처리

 
DOM 노드의 자식들을 재귀적으로 처리할 때, React는 기본적으로 동시에 두 리스트를 순회하고 차이점이 있으면 변경을 생성합니다.
 
예를 들어, 자식의 끝에 엘리먼트를 추가하면, 두 트리 사이의 변경은 잘 작동할 것입니다.
 

1
2
3
4
5
6
7
8
9
10
<ul>
  <li>first</li>
  <li>second</li>
</ul>
 
<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
cs

 

React는 두 트리에서 <li>first</li>가 일치하는 것을 확인하고, <li>second</li>가 일치하는 것을 확인합니다.
 
그리고 마지막으로 <li>third</li>를 트리에 추가합니다.
 
하지만 위와 같이 단순하게 구현하면, 리스트의 맨 앞에 엘리먼트를 추가하는 경우 성능이 좋지 않습니다.
 
예를 들어, 아래의 두 트리 변환은 형편없이 작동합니다.
 
 

1
2
3
4
5
6
7
8
9
10
<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>
 
<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>
cs

 

 

React는 <li>Duke</li>와 <li>Villanova</li> 종속 트리를 그대로 유지하는 대신 모든 자식을 변경합니다.
 
이러한 비효율은 문제가 될 수 있습니다.

 

이러한 문제를 해결하기 위해, React는 key 속성을 지원합니다.
 
자식들이 key를 가지고 있다면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인합니다.
 
예를 들어, 위 비효율적인 예시에 key를 추가하여 트리의 변환 작업이 효율적으로 수행되도록 수정할 수 있습니다.
 
 

1
2
3
4
5
6
7
8
9
10
<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>
 
<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>
cs

 

 

제 React는 '2014' key를 가진 엘리먼트가 새로 추가되었고, 
 
'2015'와 '2016' key를 가진 엘리먼트는 그저 이동만 하면 되는 것을 알 수 있습니다.
 
 
실제로, key로 사용할 값을 정하는 것은 어렵지 않습니다.
 
그리려고 하는 엘리먼트는 일반적으로 식별자를 가지고 있을 것이고,
 
그대로 해당 데이터를 key로 사용할 수 있습니다.
 
 
최후의 수단으로 배열의 인덱스를 key로 사용할 수 있지만 항목들이 재배열되는 경우
 
비효율적으로 동작합니다.
 
인덱스를 key로 사용 중 배열이 재배열되면 컴포넌트의 state와 관련된 문제가 발생할 수 있습니다.
 
배열이 재배열되면 key값도 바뀌게되고 결과적으로 컴포넌트의 state가 엉망이 되거나
 
의도하지 않은 방식으로 바뀔 수도 있습니다.
 
 
 
요약 => 자식의 대한 재귀적 처리를 효율적으로 하기 위해
 
 
출처 
 
https://ko.reactjs.org/docs/lists-and-keys.html
https://ko.reactjs.org/docs/reconciliation.html#recursing-on-children