리액트에서 key의 역할
리액트에서 동적인 배열을 렌더링해야 할 때, 자바스크립트 배열의 내장함수 map()
을 사용하여 일반 데이터 배열을 리액트 엘리먼트로 이루어진 배열로 변환해 줍니다.
하지만 그냥 map()을 사용하여 배열을 렌더링한 후 콘솔을 열어보면 다음과 같은 에러를 볼 수 있습니다. 리액트에서 배열을 렌더링할 때는 key
라는 props를 설정해야 합니다.

Key
key
는 리액트가 어떤 항목을 변경, 추가 또는 삭제할지 식별할 것을 돕습니다. key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.
예를 들어서 다음과 같이 배열을 렌더링한다고 가정해 보겠습니다.
위 배열의 b와 c 사이에 z를 삽입하게 된다면, 리렌더링을 하게 될 때 <div>b</div>
와 <div>c</div>
사이에 새 div
태그를 삽입하는 것이 아니라, 기존의 c가 z로 바뀌고, d는 c로 바뀌고 맨 마지막에 d가 새로 삽입됩니다.
그다음 a를 제거하게 된다면, 기존의 a가 b로 바뀌고, b는 z로 바뀌고, z는 c로 바뀌고, c는 d로 바뀌고, 맨 마지막에 있는 d가 제거됩니다.

이처럼 key가 없다면 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지합니다. 즉, key가 없는 경우 변경이 필요하지 않은 리스트의 요소까지 변경이 일어나게 되므로 비효율적이라고 할 수 있습니다.
이런 부분을 개선하기 위해서 key를 사용할 수 있습니다. 이번엔 객체에 key로 사용할 수 있는 고유한 값(id)을 지닌 배열이 있고, 배열의 id를 key로 사용하여 렌더링한다고 가정하겠습니다.

이처럼 리스트를 렌더링할 때 고유한 key 값이 있다면 리스트가 업데이트될 때마다 변경되지 않은 값들은 그대로 두고, 원하는 값을 삽입하거나 삭제할 수 있습니다.
key의 올바른 사용법
key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것입니다. 고유한 값은 배열이 다시 렌더링 되는 과정에서 리스트 항목의 순서를 보장할 수 있기 때문입니다. 대부분의 경우 데이터의 ID
를 key로 사용합니다. 만약 중복되는 key가 있을 때는 렌더링 시에 오류메시지가 콘솔에 나타나게 되며, 업데이트가 제대로 이루어지지 않게 됩니다
key로서의 index
렌더링 한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 항목의 index
를 key로 사용할 수 있습니다. 하지만 항목의 순서가 바뀔 수 있는 경우 key에 index를 사용하는 것은 권장하지 않습니다.
key는 리액트가 DOM 요소를 식별하는 데 사용하는 유일한 값입니다. 항목을 추가 또는 삭제할 경우, 각 항목의 index 또한 재배치됩니다. 그 결과 key를 변경시켜 렌더링 성능이 저하할 우려가 있습니다.
하지만 다음과 같은 경우, key로 index를 사용할 수 있습니다.
- 리스트와 항목이 고정되어, 다시 계산되거나 수정되지 않는다.
- 리스트의 아이템에 id가 없다.
- 리스트가 재배치되거나 필터 되지 않는다.