본문 바로가기

리액트

⭐ 8편 — 리액트 리스트 렌더링 완전 정복: key가 중요한 이유와 성능 문제까지 한 번에 이해하기

⭐ 8편 — 리액트 리스트 렌더링 완전 정복: key가 중요한 이유와 성능 문제까지 한 번에 이해하기

리액트로 화면을 만들다 보면
가장 자주 하는 작업 중 하나가 바로 배열 데이터를 화면에 반복 렌더링하는 것입니다.
게시글 목록
쇼핑몰 상품 리스트
사용자 목록
댓글 리스트
이런 기능들은 모두 배열을 map으로 돌려 렌더링하게 됩니다.
그런데 이 리스트 렌더링에서 가장 중요한 개념이 바로 key 속성입니다.
많은 초보자들이 이 key를 “그냥 넣으라고 해서 넣는 값” 정도로 생각하는데,
실제로는 리렌더링 성능에 직접적인 영향을 주는 핵심 요소입니다.
이번 글에서는 key가 왜 필요한지,
그리고 어떤 값을 key로 써야 하는지까지 실전 기준으로 설명해드릴게요.


✅ 1. 기본 리스트 렌더링 패턴.

리액트에서 리스트를 그릴 때 가장 자주 쓰는 구조는 아래처럼 map을 사용하는 방식입니다.
const items = ["사과", "바나나", "포도"];
return (
<ul>
{items.map(item => (
<li>{item}</li>
))}
</ul>
);
이 코드는 화면에는 잘 보이지만, 사실 경고가 뜹니다.
Warning: Each child in a list should have a unique "key" prop.
그 이유는 바로 key를 넣지 않았기 때문입니다.


🔥 key란 무엇인가?

간단하게 말하면,
✔ key는 React가 “어떤 요소가 어떤 데이터인지” 추적하는 식별자입니다.
리스트에서 항목이 추가되거나 삭제되면
리액트는 key를 기준으로
기존 요소인지
새로 추가된 요소인지
삭제되는 요소인지
이런 변화를 인식하게 됩니다.


🔍 key가 없으면 어떤 문제가 발생할까?

예를 들어 리스트에서 하나의 항목만 제거되었는데,
리액트는 어떤 요소가 삭제되었는지 정확히 알 수 없어 전체 리스트를 재비교하게 됩니다.
그러면
불필요한 리렌더링
UI가 순간적으로 꼬임
입력창 같은 컴포넌트가 리셋되는 문제
등이 발생합니다.
즉, key는 성능과 UI 안정성에 직접적인 영향을 줍니다.


✅ 2. key를 넣은 올바른 리스트 렌더링

<ul>
{items.map((item, index) => (
<li key={item}>{item}</li>
))}
</ul>
여기서는 item이 유일한 값이므로 key로 사용해도 괜찮습니다.
❗ 하지만 가장 위험한 key 사용법: index
많은 초보자들이 다음처럼 index를 key로 사용합니다.
<li key={index}>...</li>
하지만 index는 권장되지 않습니다.


🔥 왜 index를 key로 쓰면 안 좋을까?

이유는 간단합니다.
상황 예시
리스트:
0: "사과"
1: "바나나"
2: "포도"
여기서 "바나나"를 삭제하면 리스트가 이렇게 바뀝니다:
0: "사과"
1: "포도"
그런데 index를 key로 쓰면 리액트는 이렇게 판단합니다:
원래 index 2(포도)가 이제 index 1이 되었으니 “새로운 요소”로 인식
→ UI가 불필요하게 다시 렌더링됨
이런 문제 때문에
데이터의 고유한 값(예: id)을 key로 사용해야 합니다.


✅ 가장 좋은 key 선택 기준

✔ 1) 데이터가 가진 고유 ID
예: 유저 ID, 게시글 ID, 상품 번호 등
✔ 2) 절대 변하지 않는 값
(렌더링 때마다 달라지는 값은 절대 사용하면 안 됨)
✔ 3) 배열 index는 최후의 보류 선택(거의 쓰면 안 됨)


⭐ 실전 예제: 서버 데이터 기반 리스트

가장 일반적인 실무 예제입니다.
const products = [
{ id: 101, name: "키보드" },
{ id: 102, name: "마우스" },
{ id: 103, name: "모니터" },
];
return (
<ul>
{products.map(product => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
이렇게 ID를 key로 사용하면 최적화가 잘 작동합니다.


🔥 key를 잘못 사용해서 발생하는 실제 문제 사례

✔ 1) 리스트가 리렌더링될 때 입력값이 초기화됨
폼이 포함된 리스트에서 index를 key로 쓰면 자주 발생합니다.
✔ 2) 애니메이션이 깨짐
React Transition, Framer Motion 등 애니메이션 사용하는 UI에서 특히 심각합니다.
✔ 3) “삭제/추가” 연산 시 엉뚱한 요소가 업데이트됨
리액트가 같은 요소인지 판단하지 못해 생기는 문제입니다.


🚨 초보자가 리스트 렌더링에서 실수하는 4가지

❌ 1) key를 아예 넣지 않음
React가 항목을 제대로 비교하지 못함
❌ 2) key로 index 사용
정렬, 추가, 삭제 시 문제가 바로 발생
❌ 3) key가 중복되는 값
중복된 key는 아무 의미가 없습니다.
오히려 업데이트 로직이 꼬입니다.
❌ 4) key를 위한 랜덤값 생성
Math.random()으로 만든 key는 렌더링마다 바뀌기 때문에 최악입니다.


✨ 마무리: key는 “리액트가 리스트를 관리하는 기준”

리스트 렌더링은 단순히 map으로 돌리는 작업이 아닙니다.
리액트가 어떤 요소를 어떤 값과 연결해서 추적하는지를 결정하는 중요한 작업입니다.
key를 올바르게 사용하면
✔ 성능이 좋아지고
✔ UI 변화가 안정적이고
✔ 버그도 크게 줄어듭니다.
이번 글을 이해했다면
실무에서 리스트를 다루는 능력이 확 올라가게 될 거예요.