💻데브노트소개
🎨

React key는 왜 index를 쓰면 안 될까: 리스트 렌더링의 함정

데브노트 편집팀·2026.06.08·6분 읽기
X(트위터)
ADVERTISEMENT

map으로 리스트를 그릴 때 React가 던지는 그 경고, "각 자식에 고유한 key가 필요합니다." 그냥 index를 넣어 끄고 넘어가면 미묘한 버그가 따라옵니다.

key는 "이 항목이 그 항목"임을 알려주는 신원증

React는 리렌더 시 이전 트리와 새 트리를 비교(재조정)합니다. 이때 key같은 항목인지 판별합니다. key가 안정적이면 React는 DOM을 새로 만들지 않고 재사용합니다.

{todos.map((todo) => (
  <TodoItem key={todo.id} todo={todo} />  // ✅ 안정적 고유 id
))}

index를 key로 쓰면 생기는 일

목록의 순서가 바뀌거나 중간이 삽입/삭제되면, index 기반 key는 "다른 데이터에 같은 key"를 부여하게 됩니다. React는 같은 항목으로 착각하고 상태를 엉뚱한 행에 붙입니다.

// 입력값이 있는 행을 맨 앞에 추가하면...
{items.map((item, i) => (
  <input key={i} defaultValue={item.name} />  // ❌
))}
// → 입력 중이던 텍스트가 다른 행으로 옮겨 붙는 버그

체크박스 상태, 포커스, 입력값처럼 DOM에 사는 상태가 뒤섞입니다.

언제 index가 그나마 괜찮은가

다음을 모두 만족할 때만:

  1. 목록이 정적(추가·삭제·정렬 없음)
  2. 항목에 고유 id가 없음
  3. 항목 자체에 상태가 없음

하나라도 어기면 고유 id를 만들어 쓰세요. 서버 데이터엔 보통 id가 있고, 없으면 생성 시 crypto.randomUUID()로 부여할 수 있습니다.

key는 형제 안에서만 유일하면 된다

전역 유일일 필요는 없습니다. 같은 map 안의 형제끼리만 구분되면 충분합니다.

마무리 체크리스트

  • key의 역할은 재조정 시 항목 식별
  • 순서·삽입·삭제가 있으면 index key 금지
  • 안정적인 고유 id를 key로
  • id가 없으면 데이터 생성 시점에 부여

"리스트가 변하는가?"에 '예'라면, key는 무조건 안정적인 id여야 합니다.

#React#함정#성능#렌더링
X(트위터)
ADVERTISEMENT