리액트는 map()
고차함수를 이용해 list를 렌더링 시 key props를 전달해주어야 한다.
공식문서에 따르면 key는 배열 안의 형제 사이
에서 고유해야 한다. 즉 children의 key만 서로 다르면 된다. 따라서 index를 사용해도 children의 key가 서로 다를테니 same key에러가 발생할 이유가 없으므로 상관없을 것 같기도 하다.
하지만 index를 key props로 지정하게 된다면 list 요소가 추가 삭제가 이루어질 때 reindexing
으로 인해 list의 모든 형제 컴포넌트가 재렌더링
이 되기에 사용하면 안 된다!
해당 포스팅은 왜 list 요소가 추가 삭제될 때 reindexing이 일어나고, 왜 reindexing으로 모든 list 컴포넌트들이 재렌더링되는지를 서술하고자 한다.
설명하기 앞서 key prop에 고유한 값(ex. id)와 index를 각각 지정 시 차이점에 대해 설명하기 위해 위의 데모를 만들어보았다.
버튼을 클릭할 때마다 배열의 맨 처음 원소로 새로운 아이템이 추가된다.
콘솔창을 보면 고유한 값인 id를 key prop으로 지정할 때, 새로 추가된 아이템만이 렌더링되고 있음을 확인할 수 있다.
버튼을 클릭할 때마다 배열의 맨 처음 원소로 새로운 아이템이 추가된다.
콘솔창을 보면 map()의 index key prop으로 지정할 때, list 전체가 재렌더링되고 있음을 확인할 수 있다.
A. 이유는 간단하다.
리액트에서 props가 변경되면 컴포넌트를 재렌더링하기 때문이다.
배열에서 list 요소를 추가 삭제하면 reindexing 되는데, index를 key prop으로 지정하게 되면 index가 변경된 컴포넌트에 대해 재렌더링이 이루어지게 되는 것이다.
위의 demo의 경우에도 새로운 item을 arr의 맨 첫 번째 원소로 추가하기 때문에, 기존 arr의 item의 index가 +1이 된다. 따라서 모든 card가 재렌더링된 것이다.
따라서 key prop에는 item의 id를 지정하거나, react uid 라이브러리를 이용해 고유한 key를 지정해주어야 한다.
React에서 list를 렌더링 시 key prop에 index를 사용했을 때의 문제점은 프론트엔드 면접의 단골 질문이다.
이 포스팅이 프론트엔드 면접 준비를 하거나 리액트의 key prop에 대해 궁금하셨던 분에게 조금이라도 도움이 되었기를 바란다.
(ref)