본문으로 바로가기

[React] map에서 key를 사용하는 이유, 주의점

블로그 게시글 중 Warning: Each child in a list should have a unique "key" prop. 의 에러를 다루는 게시글이 있다. (게시글 이동하기) 그런데 해당 게시글에 왜 key를 사용해야 하는 지?에 대해 문의 댓글이 달려 한번 알아보려고 한다.

key를 사용하지 않으면 ???

DOM 노드의 자식을 재귀적으로 처리하는 경우 React에서는 동시에 2개 리스트를 순회하고 차이가 있는 경우 변경을 생성한다. 이게 무슨 말이냐? 아래 예시를 확인해보자.

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

 

이전 리스트에는 third가 없고 이후 리스트에는 third가 있으니 변경이 일어난 것이다. 따라서 트리 마지막에 third 자식만 추가하면 변경이 끝이난다. 즉 마지막 third 자식만 트리에 넣어주고 끝이난 것이다. 그러나 아래의 경우는 어떨까?

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>zero</li>
  <li>first</li>
  <li>second</li>
</ul>

 

이전 리스트에는 zero가 없고 이후 리스트에는 zero가 있으니 변경이 일어난 것이다. 따라서 트리 첫번째 자식만 추가하면 변경이 끝이난다. 그러나 마지막 추가가 아닌 리스트의 중간(+첫번째)에 추가하는 것매우 큰 비용이 발생한다. 첫번째 자식에 zero를 추가하는 과정에서 어떠한 문제가 생길까? 첫번째 zero를 추가하면 트리의 모양zero(1), first(2), second(3)이 된다. 따라서 zero 이후의 노드는 모두 변경이 일어나 다시 그려지게 된다. 지금은 고작 2개이지만 100, 1000 개가 있다는 가정하에 많은 변화가 일어날 것이다. 그럼 이 문제를 어떻게 하면 해결할 수 있을까? key를 사용하면 된다.

key 잘 사용하기

key를 사용하면 사용하는거지 잘 사용하는 것은 뭘까? react map의 key는 같은 map 형제에서 고유한 값이어야 한다. 즉 중복이 되면 안된다. 왜 그럴까? key는 변화를 감지하기 위해서 필요하다. 그런데 중복되면 변화하여도 어떠한 key를 가진 노드가 변경되었는 지 알 수 없기 때문이다. 그럼 map 함수에서 제공하는 index를 사용해도 될까? 이건 될 수도 있고 안될 수도 있다. 즉 상황에 따라 개발자가 판단하여 key 값을 주어야 한다. key를 index로 사용해도 되는 경우사용하면 문제가 되는 경우 2가지 모두 알아보자.

◆ key를 index로 사용하면 안되는 경우

index를 key로 사용하면 생기는 문제는 정렬, 변경과 같은 배열에 이벤트가 발생했을 때 일어난다. 이 경우 state 값을 가지고 있으면 state에 관련하여 문제가 생길 수도 있다. 즉 개발자가 원하는 방향이 아닌 다른 방향으로 코드가 동작할 수 있다는 것이다. 아래 코드를 직접 사용하며 결과를 확인해보자. (공식 문서에서 제공하는 코드를 hook으로 변경)

 

See the Pen Untitled by Codiving (@codiving) on CodePen.

 

위 코드를 실행하면 알 수 있듯이 index를 key로 사용하는 경우는 해당 item의 위치에 따라 key가 변한다. 따라서 input에 담겨있는 value의 위치가 우리가 생각한 것과 다르게 동작하는 것을 확인할 수 있다. 그러나 key를 id로 사용한 경우는 우리가 원하는 대로 정상적으로 동작하는 것을 확인할 수 있다.

 

◆ key를 index로 사용해되 되는 경우

위에서 계속 언급하였지만 key의 존재 이유는 tree가 변경이 일어났을 때 DOM 노드 그리는 작업을 더 효율적으로 하기 위해서이다. 그러나 만약 배열이 정적으로 정해져있고 정렬, 변화, 필터링 등 어떠한 이벤트를 주지 않는 경우는 tree가 변경될 경우가 없다. 즉 이러한 경우는 index를 key로 사용하여도 문제가 되지 않는다.

 

이번 게시글에서는 react map에서 key를 사용하는 이유를 알아보았다. 그리고 더 깊게 key를 어떻게 하면 잘 사용할 수 있는 지? anti 패턴인 index를 key로 사용하면 안되는 이유index를 key를 사용해도 되는 경우를 알아보았다.

 

참고자료

 

마지막

해당 내용은 틀릴 수도 있습니다. 틀린 내용이 있으면 조언 부탁드립니다.

반응형