React JSX의 List Rendering에서 key값 설정하기 (.map)

React에서 구조화된 객체를 여럿 가지는 배열을 통해서 List를 그리는 전형적인 패턴이 있다.

const data = [{
  title: "hi",
  content: "hello"
}, 
...
{
  title: "bye",
  content: "sad"
}]

해당 데이터를 React는 다음과 같이 그린다.

function App() {
  return (
     <div>
       {data.map(el => (
           <div>
              <h1>{el.title}<h1/>
              <p>{el.content}<p/>
           </div>
       ))}
     </div>
  )
}

React에 익숙하다면, 위의 코드에서 경고 메세지를 예상할 수 있을 것이다.

바로, key prop을 설정하라는 메세지이다.

Warning: Each child in a list should have a unique “key” prop.

이 경고를 없애기 위해서 주로 사용되는 key 값은 index, 서버에서 받아온 데이터라면 (아마 있을) pk id값, 아니면 nanoid나 lodash와 같은 라이브러리로 생성해낸 유니크한 id값 일 수도 있다.

 

다만, 위의 경우의 수 에서 pk id값을 제외한 나머지는 바람직한 key값은 되지 못한다.

바람직한 key값은 데이터 항목의 고유한 식별자(ID)이기 때문이다.

❄️ key값은 보통 문자열 혹은 숫자를 사용하게 된다.

 

key값을 바탕으로 React는 해당 데이터의 배열에서 어떤 값이 변경되었고 추가되었는지 추론하고 이를 바탕으로 DOM을 올바르게 업데이트할 수 있다.

따라서, 개발자는 올바른 Key값을 제공하여야 한다.

 

배열의 추가 혹은 삭제로 index값은 변동될 수 있다. 따라서, 배열의 index값은 key에 적절하지 않다.

nanoid와 같이 랜덤으로 생성해낸 유니크한 id값도 적절하지 않을 수 있는데, 리렌더링 될 때 이 함수가 다시 실행되어 값이 변동되는 경우에는 적절하지 않을 수 있다.

🐝 랜덤으로 생성되는 key prop의 경우 같은 데이터를 다른 데이터로 판단하여 불필요한 리랜더링이 발생할 여지가 있다.
이를 방지하기 위해서 랜덤 값에 메모제이션을 사용하는 방법도 있다.

 

🐳 가장 적절한 패턴은 구조화된 데이터 내부의 유니크한 값을 key로 사용하는 것이다.

서버에서 가져온 데이터를 기반으로 이를 생각해보면, primary key가 이 정의에 가장 부합하므로, 일반적으로 데이터 객체 내부의 id값을 key값으로 많이 사용한다.

 

 

 

🌧️ 참고 공식 문서

https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key

 

Rendering Lists – React

The library for web and native user interfaces

react.dev