[React]🔑배열의 index를 key로 사용하면 안되는 이유
0. 들어가면서
React에서 리스트를 렌더링할 때, key props는 필수입니다. 많은 초보 개발자들이 편의상 index를 key로 사용하곤 하는데요, 사실 이것은 예기치 못한 버그의 원인이 될 수 있습니다.
저도 여러 프로젝트를 진행하면서 분명 리스트의 순서가 제 의도와는 맞지 않게 변경되거나
리렌더링되는 현상을 경험한 적이 있습니다.
이번 포스팅에서는 왜 index를 key로 사용하면 안 되는지, 어떤 문제가 발생할 수 있는지, 그리고 어떤 대안을 사용하는 것이 좋은지를 정리해보겠습니다.
1. 🔑 key란 무엇인가?
React는 리스트를 렌더링할 때 각 요소를 효율적으로 추적하고 업데이트하기 위해 key라는 고유한 식별자가 필요합니다.
key를 통해 어떤 요소가 변경되었고, 추가되었으며, 제거되었는지 정확하게 판단할 수 있습니다.
const list = ['a', 'b', 'c'];
return (
<ul>
{list.map((item, index) => (
<li key={index}>{item}</li> // ❌ 문제의 원인
))}
</ul>
);
2. index를 key로 쓰면 안되는 이유
2-1. 리렌더링 시 잘못된 DOM 재사용 발생
React는 key를 기준으로 요소의 동일성을 판단합니다. index는 리스트 변경 시 위치가 바뀔 수 있기 때문에, 실제 데이터는 바뀌었지만 key는 그대로라면 DOM이 잘못 재사용될 수 있습니다.
더 쉽게 설명하면,
배열의 인덱스를 key 값으로 사용하면 안 되는 이유는 순서가 변경되어도 동일한 key 값이 유지되기 때문입니다. A,B,C 순서로 rendering되어 있던 컴포넌트가 C,B,A 순서로 변경되어도 key값은 동일하기 때문에, 재조정 단계에서 re-rendering 대상으로 식별하지 않을 가능성이 생깁니다. 따라서, 배열 내에서 순서가 변경되어도 각 컴포넌트의 key값이 변경되지 않는 고유한 값으로 설정해야 합니다.
📌 예시
const [list, setList] = useState(['Apple', 'Banana', 'Orange']);
만약 중간에 Banana를 삭제한다면, React는 다음과 같이 판단할 수 있습니다.
index | before | after | React가 판단한 변화 |
0 | Apple | Apple | 그대로 유지 |
1 | Banana | Orange | Banana → Orange로 바뀌었다고 착각 |
2 | Orange | - | 삭제됨 |
→ 실제로는 Banana가 삭제되고 Orange는 그대로인데, React는 잘못된 DOM 업데이트를 하게 됩니다.
2-2. 사용자 입력 상태 손실
입력 필드가 포함된 리스트에서 index를 key로 쓰면, 포커스가 풀리거나 입력한 값이 날아가는 문제가 발생할 수 있습니다.
{list.map((item, index) => (
<input key={index} defaultValue={item} />
))}
중간 아이템을 삭제하거나 순서를 바꾸면, React는 input 요소를 잘못 판단해서 새로운 값으로 교체하거나 focus를 잃게 됩니다.
3. key는 어떻게 설정해야 할까?
3-1. 고유한 ID 사용
가장 좋은 방법은 데이터에 고유한 ID가 포함되어 있을 때 그 ID를 key로 사용하는 것입니다.
const list = [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Orange' },
];
{list.map((item) => (
<li key={item.id}>{item.name}</li> // ✅ 안정적인 key
))}
3-2. ID가 없다면?
- 고유한 값(item 자체)을 key로 쓸 수 있다면 그 방법도 가능.
- 하지만 최후의 수단으로만 index를 사용하는 것이 좋습니다.
(예: 리스트가 절대 변경되지 않는 경우, 정적 목록 등)
4.💡정리하며
key로 index | 왜 안 좋은가 |
🔁 재사용 문제 | 잘못된 DOM 업데이트 발생 가능 |
🎯 상태 손실 | focus, 입력 값 등 날아갈 수 있음 |
🔍 디버깅 어려움 | 예측 불가능한 렌더링 문제 발생 |
한 마디로 데이터가 변하는 배열이라면 index를 key로 사용하지 않는 습관을 들이는 것이 좋을 것 같습니다.
📚 참고자료