React에서 map을 사용할 때 key의 의미와 중요성
key의 기본 의미
React에서 key는 배열의 각 요소를 고유하게 식별하기 위한 특수 문자열 속성입니다. React가 Virtual DOM에서 어떤 항목이 변경, 추가 또는 제거되었는지 식별하는 데 도움을 줍니다.
key의 핵심 역할
1. 성능 최적화 (가장 중요한 역할)
// key가 없을 때: React는 모든 요소를 재렌더링
{items.map(item => (
<ListItem item={item} /> // ❌ 성능 저하
))}
// key가 있을 때: 변경된 요소만 정확히 업데이트
{items.map(item => (
<ListItem key={item.id} item={item} /> // ✅ 성능 최적화
))}
2. 상태 유지 보장
const todos = [
{ id: 1, text: "리액트 학습", completed: false },
{ id: 2, text: "과제 제출", completed: true }
];
function TodoList() {
return (
<ul>
{todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
// ✅ 체크박스 상태가 정확히 유지됨
/>
))}
</ul>
);
}
key가 필요한 이유: 구체적인 예시
❌ key가 없을 때 발생하는 문제
// 초기 배열
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
// 배열에서 Bob 제거 후
const updatedUsers = [
{ id: 1, name: 'Alice' },
{ id: 3, name: 'Charlie' }
];
// key 없이 렌더링하면 React가 혼동함
{users.map(user => <div>{user.name}</div>)}
/*
Alice
Bob ❌ 삭제해야 할 요소
Charlie
*/
// React는 인덱스를 기준으로 판단하므로
// Bob이 사라지면 Charlie가 Bob의 위치로 이동한 것으로 인식
✅ key를 사용한 올바른 예
{users.map(user => (
<div key={user.id}>{user.name}</div>
))}
/*
key="1" -> Alice
key="2" -> Bob ✅ 정확히 삭제됨
key="3" -> Charlie
*/
key 선택 가이드라인
✅ 권장되는 key 값
// 1. 데이터베이스 ID (가장 이상적)
{posts.map(post => (
<Post key={post.id} post={post} />
))}
// 2. 고유한 문자열 조합
{items.map(item => (
<Item key={`${item.category}-${item.timestamp}`} item={item} />
))}
// 3. UUID 등 고유 식별자
{users.map(user => (
<User key={user.uuid} user={user} />
))}
⚠️ 조건부로 사용 가능한 key
// 4. 배열 인덱스 (순서가 절대 변경되지 않을 때만)
{staticList.map((item, index) => (
<StaticItem key={index} item={item} />
))}
❌ 절대 사용하지 말아야 할 key
// 5. Math.random() (매 렌더링마다 변경됨)
{items.map(item => (
<Item key={Math.random()} /> // ❌ 매우 나쁨
))}
// 6. Date.now() (항상 변경됨)
{items.map(item => (
<Item key={Date.now()} /> // ❌ 매우 나쁨
))}
// 7. 중복된 값
{items.map(item => (
<Item key="same-key" /> // ❌ 안됨
))}
실제 React 내부 동작 방식
Virtual DOM 비교 알고리즘
// Before: [A, B, C] -> After: [A, C]
{items.map(item => <Item item={item} />)}
// key 없음: React는 인덱스로 비교
// 0: A -> A (재사용)
// 1: B -> C (B를 C로 변경) ❌ 비효율적
// 2: C -> (삭제)
// key 있음: React는 key로 비교
// key="a": A -> A (재사용)
// key="b": B -> (삭제) ✅ 효율적
// key="c": C -> C (재사용)
다양한 시나리오별 key 사용법
1. 중첩 배열에서의 key
const categories = [
{
id: 1,
name: "전자제품",
products: [
{ id: 101, name: "스마트폰" },
{ id: 102, name: "노트북" }
]
},
{
id: 2,
name: "의류",
products: [
{ id: 201, name: "셔츠" },
{ id: 202, name: "바지" }
]
}
];
function CategoryList() {
return (
<div>
{categories.map(category => (
<div key={category.id}>
<h2>{category.name}</h2>
{category.products.map(product => (
<Product
key={product.id} // ✅ 각 수준마다 고유 key 필요
product={product}
/>
))}
</div>
))}
</div>
);
}
2. 필터링/정렬 시 key 중요성
const tasks = [
{ id: 1, text: "회의", priority: "high" },
{ id: 2, text: "이메일", priority: "low" },
{ id: 3, text: "보고서", priority: "high" }
];
function TaskList({ showHighPriorityOnly }) {
const filteredTasks = showHighPriorityOnly
? tasks.filter(task => task.priority === "high")
: tasks;
return (
<ul>
{filteredTasks.map(task => (
<TaskItem
key={task.id} // ✅ 필터링해도 상태 유지
task={task}
/>
))}
</ul>
);
}
key 관련 디버깅 팁
일반적인 에러 메시지
Warning: Each child in a list should have a unique "key" prop.
해결 방법
// ❌ 문제: key 누락
{users.map(user => <User user={user} />)}
// ✅ 해결 1: 고유 ID 사용
{users.map(user => <User key={user.id} user={user} />)}
// ✅ 해결 2: 안정적인 key 생성
{users.map((user, index) => (
<User key={`user-${user.name}-${index}`} user={user} />
))}
// ✅ 해결 3: 데이터 수정 시 key 유지
const updatedUsers = users.map(user =>
user.id === targetId
? { ...user, name: newName } // ✅ key 유지
: user
);
결론
React에서 key는:
- 성능 최적화를 위한 필수 요소
- 상태 보존을 보장하는 장치
- 변경 감지를 정확하게 하는 식별자
- 고유성과 안정성이 가장 중요한 속성
항상 안정적이고 예측 가능한 고유 key를 사용해야 React 애플리케이션의 성능과 안정성을 보장할 수 있습니다.
Die Bedeutung und Bedeutung des Schlüssels bei der Verwendung von MAP in React
'프로그래머로의 여정' 카테고리의 다른 글
| [코드분석] 코드에서 key의 의미 (0) | 2025.09.04 |
|---|---|
| JS에서 key는 무엇인가 (0) | 2025.09.04 |
| JavaScript, React Array.map() (0) | 2025.09.04 |
| CSS 의사 클래스 선택자(pseudo-class selector) 란? (0) | 2025.09.03 |
| _fonts.scss에서 밑줄(_)을 앞에 붙이는 이유 (0) | 2025.09.02 |