React는 이전 리스트와 현재 리스트를 순회하고 차이점이 있으면 변경을 생성한다.
예를 들어 맨 끝에 엘리먼트를 추가한다면, 변경은 잘 작동할 것이다.
<ul>
<li>first</li>
<li>second</li>
</ul>
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
React는 첫번째, 두번째 요소가 같은 것을 확인하고, 마지막에
하지만 위와 같이 구현할 경우에 리스트의 맨 앞에 엘리먼트를 추가하는 경우 성능이 좋지 않다.
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
첫번째 부분, 두번째 부분, 세번째 부분 모두 다 다르다고 판단하기 때문에 모든 자식을 변경하게 된다. 이러한 방식은 효율적이지 못 하다.
이러한 문제를 해결하기 위해 React는 key 속성을 지원한다. 자식들이 가지고 있는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인한다.
<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>
이제 각각이 key를 가지고 있기 때문에 맨 앞에 요소를 추가하더라도 "2015", "2016" key를 가진 자식은 그냥 이동만 하면 된다는 것을 알 수 있다.
key값은 한 배열에서 고유한 값을 넣어주어야 하며 각각의 data의 식별자를 넣어주면 된다. 만약 식별자인 id를 가지고 있지 않다면 shortId 같은 라이브러리를 사용하거나 배열의 index를 key로 넣어줄 수도 있다.
하지만 key를 배열의 index로 사용하는 것은 지양해야한다. 만약 배열이 절대 변경되지 않는다고 판단이 된다면 index로 사용해도 잘 작동한다. 하지만 재배열 될 경우에는 매우 비효율적으로 작동할 것이다.
컴포넌트 인스턴스는 key를 기반으로 갱신 되고 재사용 된다. index를 key로 사용하면, 항목의 순서가 바뀌었을 경우에 key 또한 바뀔 것이다. 그 결과로, 컴포넌트의 state가 엉망이 되거나 의도하지 않은 방식으로 바뀔 수도 있다.
index를 key로 쓰기 위해서는 다음과 같은 상황에서만 사용해야한다.
위 사항을 충족할 때에만 index를 key로 사용하고 웬만해서는 id라던지 shortId라이브러리를 활용해서 사용하도록 하자.
참고 자료
https://ko.reactjs.org/docs/lists-and-keys.html
https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318