React의 map함수에서 index를 key로 사용해도 되는가?!

Map의 자세한 사용법은 여기로

React.js의 map 함수에서 key에 index를 써도 되는지에 대해 확인하는 포스팅입니다.

map()은 배열의 각 요소를 반복하고, 새로운 배열을 반환합니다.
React에서는 배열의 요소를 컴포넌트로 변환하여 렌더링할 때 map이 사용합니다.

왜 for을 사용하지 않고 map을 사용하는가?

for문은 반환 값이 없는 명령문인데 반해, map은 새로운 배열을 반환하는 표현식이기 때문에 JSX 내에서 바로 사용할 수 있습니다. 이러한 이유로 map을 사용합니다.

map 사용법

const items = ["Item 1", "Item 2", "Item 3"];
 
function MyList() {
  return (
    <ul>
      {items.map((item, index, array) // map은 배열의 각 요소에 대해 콜백 함수를 실행합니다.
      // item: 현재 배열 요소, index: 현재 요소의 인덱스, array: 원본 배열
      => (
        <li
          key={index}
          className={array[0] === item ? "font-bold" : "font-normal"}
        >
          {item}
        </li>
      ))}
    </ul>
  );
}

왜 map의 key는 index를 쓰면 안될까?

key는 React가 어떤 요소가 변경되었는지를 식별하는 데 사용되며, 이는 애플리케이션의 성능을 개선하는 데 도움을 줄 수 있습니다.

그러나 흔한 실수 중 하나는 요소의 index를 key로 사용하는 것입니다.

겉보기에는 합리적인 해결책처럼 보일 수 있지만, 리스트의 순서가 변경되었을 때 문제가 발생할 수 있습니다.

리스트의 순서가 바뀌면, React는 어떤 요소가 변경되었는지 올바르게 식별하지 못하고, 그 결과 불필요한 DOM 업데이트가 발생하게 됩니다.

이는 애플리케이션의 성능 저하로 이어질 수 있습니다.

다음과 같이 React 애플리케이션에서 렌더링할 항목의 리스트가 있다고 가정해 보겠습니다.
API를 통해 데이터를 가져와서 map() 함수를 사용해 화면에 표시합니다.

const items = [
  { id: 1, name: "Item 1" },
  { id: 2, name: "Item 2" },
  { id: 3, name: "Item 3" },
];
 
function MyList() {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item.name}</li>
      ))}
    </ul>
  );
}

이 상태에서는 모든 것이 정상적으로 작동하며, 리스트는 다음과 같이 올바르게 렌더링됩니다:

하지만 여기서 Item 2와 Item 3의 위치를 바꾸기로 했다고 가정해 보겠습니다.

const items = [
  { id: 1, name: "Item 1" },
  { id: 3, name: "Item 3" },
  { id: 2, name: "Item 2" },
];

이제 같은 map() 함수를 사용해 리스트를 다시 렌더링하려고 하면, index를 key로 사용하는 한 React는 변경된 요소를 제대로 식별할 수 없습니다.

그 결과, React는 리스트의 모든 항목을 다시 업데이트하게 되며, 실제로는 Item 2와 Item 3의 위치만 변경된 것임에도 불필요한 DOM 업데이트가 발생합니다.

이런 방식은 요소가 많은 대규모 애플리케이션에서 성능 문제로 이어질 수 있습니다.


결론

앞서 사용한 index 대신 고유한 식별자(id 등)을 이용하여 key를 사용하는 것이 좋습니다.

백엔드로부터 제공받지 않은 경우 동적으로 임의의 key를 부여할 수 있으나 이는 임시방편일 뿐 좋은 방법이라고 보기 힘듭니다.

꼭 백엔드로 부터 id를 달라고 요청하세요~!!