728x90
반응형
리액트에서 `index`를 key로 사용하는 것은 권장되지 않는 이유는 배열의 요소들이 추가되거나 삭제될 때, 배열의 순서가 바뀌는 경우 문제가 발생할 수 있기 때문입니다.
리액트에서 `key`를 통해 리스트에서 어떤 요소가 변경, 추가, 삭제됐는지를 추적합니다. 그러나 index를 key로 사용하면 배열의 순서가 변경될 때 리액트가 요소들을 잘못 인식할 수 있습니다. 예를 들어 배열에 새로운 요소가 중간에 추가되면 그 뒤에 있는 요소들의 인덱스가 모두 변경되게 된다. 리액트는 이를 새로운 요소로 인식해 불필요하게 재렌더링을 하거나, 요소의 상태를 잘못 처리할 수 있습니다.
// 초기 상태의 할일 목록
const todos = [
{ text: '운동하기' }, // index: 0
{ text: '공부하기' }, // index: 1
{ text: '청소하기' } // index: 2
];
// '독서하기'를 첫 번째로 추가하면
const newTodos = [
{ text: '독서하기' }, // index: 0 (새로운 항목)
{ text: '운동하기' }, // index: 1 (기존 index 0)
{ text: '공부하기' }, // index: 2 (기존 index 1)
{ text: '청소하기' } // index: 3 (기존 index 2)
];
이로 인해 성능 문제가 발생하거나, 사용자 입력 상태 같은 요소가 의도치 않게 초기화되는 등 예기치 않은 버그가 생길 수 있습니다. 그래서 배열의 순서나 요소 변경에 영향을 받지 않는 고유한 값을 key로 사용하는 것이 좋습니다.
상태 관리 문제
const items = ['A', 'B', 'C'];
items.map((item, index) => (
<input key={index} defaultValue={item} />
));
// 'B'가 삭제되면 'C'의 index가 1로 변경되어
// 이전 'B'의 input 상태를 물려받게 됨
성능 저하
- 순서 변경 시 모든 컴포넌트가 재렌더링
- Virtual DOM 비교 작업 증가
- 애니메이션/트랜지션 오작동 → key가 바뀌면서 의도하지 않은 애니메이션 발생
대안
key는 데이터의 유일성을 보장하고 변하지 않는 값을 사용하는 것이 중요합니다. 서버의 데이터 베이스에서 제공하는 고유 ID를 사용하는 것이 일반적입니다. 또한 `UUID` 같이 전역적으로 고유한 ID를 생성이 가능한 라이브러리를 사용할 수 있습니다.
// 고유 ID 사용
items.map(item => (
<Component key={item.id} />
));
// 안정적인 값 조합
items.map(item => (
<Component key={`${item.category}-${item.name}`} />
));
728x90
반응형