ReactJS - 키: 효율적인 목록 렌더링의 힘을 해제하는 열쇠
안녕하세요, 미래의 React 슈퍼스타 여러분! 오늘 우리는 React에서 가장 중요한 개념 중 하나인 키에 대해 배울 것입니다. 프로그래밍에 새로운 사람이라면 걱정하지 마세요 - 저는 여러분을 단계별로 안내할 것입니다. 수년 동안 수많은 학생들을 가르친 경험을 바탕으로 말이죠. 그럼 커피(또는 차, 당신이 좋아하는 음료라면)를 한 잔 챙겨서, 이 흥미로운 여정에 함께 동참해 보세요!
목록과 키 이해하기
React에서 목록이란?
키에 대해 이야기하기 전에, 먼저 목록에 대해 이야기해 보겠습니다. React에서 우리는 종종 페이지에 여러 개의 유사한 항목을 표시해야 합니다. 예를 들어, 할 일 목록, 쇼핑 카트, 또는 당신의 좋아하는 영화 목록을 생각해 보세요. React에서는 이러한 목록을 표현하기 위해 JavaScript 배열을 사용하고, 이를 컴포넌트에서 렌더링합니다.
간단한 예제를 보겠습니다:
function MovieList() {
const movies = ['Inception', 'Interstellar', 'The Dark Knight'];
return (
<ul>
{movies.map(movie => <li>{movie}</li>)}
</ul>
);
}
이 코드에서 우리는 map
함수를 사용하여 영화 제목의 배열을 <li>
요소의 배열로 변환하고 있습니다. 꽤 쉬운东西이죠?
키 프로프 Enter
이 코드를 실행하면 콘솔에 다음과 같은 경고 메시지를 볼 수 있습니다:
Warning: Each child in a list should have a unique "key" prop.
이제 우리의 스타가 등장합니다 - key
프로프입니다!
키는 무엇인가요?
키는 React가 목록의 어떤 항목이 변경되었는지, 추가되었는지, 또는 제거되었는지 식별하는 데 도움을 주는 특별한 문자열 속성입니다. 목록의 각 항목에 고유한 이름 태그를 달아주는 것과 같습니다.
우리의 이전 예제를 수정하여 키를 포함시키겠습니다:
function MovieList() {
const movies = [
{ id: 1, title: 'Inception' },
{ id: 2, title: 'Interstellar' },
{ id: 3, title: 'The Dark Knight' }
];
return (
<ul>
{movies.map(movie => <li key={movie.id}>{movie.title}</li>)}
</ul>
);
}
이제 각 <li>
요소에 고유한 key
프로프가 있습니다. React는 이 키를 사용하여 목록이 변경될 때 효율적으로 업데이트합니다.
키의 마법
키가 왜 중요한가요?
키를 사용하면 React가 다음과 같은 작업을 수행하는 데 도움이 됩니다:
- 목록의 항목이 변경되었는지, 추가되었는지, 제거되었는지 식별
- 재랜더링 사이의 컴포넌트 상태 유지
- DOM 조작을 최소화하여 성능 향상
적절한 키 선택
이제 "키로 무엇을 사용해야 할까요?"라는 질문이 드는 것 같습니다. 훌륭한 질문입니다! 다음과 같이 설명드리겠습니다:
- 고유하고 안정적인 ID 사용: 데이터가 데이터베이스에서 오는 경우, 항목의 ID를 키로 사용합니다.
<li key={item.id}>{item.name}</li>
- 항목의 인덱스를 마지막 수단으로 사용: 안정적인 ID가 없는 경우, 배열의 인덱스를 사용할 수 있습니다. 하지만 목록이 재정렬될 수 있다면 문제가 발생할 수 있습니다.
{items.map((item, index) => <li key={index}>{item.name}</li>)}
-
고유한 키 생성: 항목을 실시간으로 생성하는 경우,
uuid
와 같은 패키지를 사용하여 고유한 키를 생성할 수 있습니다.
import { v4 as uuidv4 } from 'uuid';
{items.map(item => <li key={uuidv4()}>{item.name}</li>)}
키와 인덱스: 좀 더 깊이 탐구하기
이제 기본 개념을 이해했으므로, 인덱스를 키로 사용하는 것에 대해 좀 더 깊이 탐구해 보겠습니다.
인덱스를 키로 사용할 때
인덱스를 키로 사용하는 것은 유혹적입니다. 왜냐하면 그것이 간편하고 언제나 사용 가능하기 때문입니다. 그러나 다음과 같은 경우에만 사용하는 것이 좋습니다:
- 목록이 정적이고 변경되지 않을 때
- 목록의 항목에 안정적인 ID가 없을 때
- 목록이 재정렬되거나 필터링되지 않을 때
인덱스를 키로 사용하는 것이 적절한 예제:
function StaticList() {
const items = ['Apple', 'Banana', 'Cherry'];
return (
<ul>
{items.map((item, index) => <li key={index}>{item}</li>)}
</ul>
);
}
인덱스를 키로 사용하는 위험
다음과 같은 동적인 예제를 통해 인덱스를 키로 사용하는 것이 문제가 될 수 있는 이유를 이해해 보겠습니다:
function DynamicList() {
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const addItem = () => {
setItems(['New Item', ...items]);
};
return (
<>
<button onClick={addItem}>Add Item</button>
<ul>
{items.map((item, index) => (
<li key={index}>
{item}
<input type="text" />
</li>
))}
</ul>
</>
);
}
이 예제에서 새 항목을 추가하고 입력 필드에 무언가를 입력한 후, 입력 값이 섞이는 것을 발견할 수 있습니다. 이는 React가 인덱스를 키로 사용하고 있기 때문입니다.
더 나은 접근 방식
이 문제를 해결하기 위해, 우리는 안정적이고 고유한 식별자를 사용해야 합니다:
function DynamicList() {
const [items, setItems] = useState([
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
]);
const addItem = () => {
const newItem = { id: Date.now(), text: 'New Item' };
setItems([newItem, ...items]);
};
return (
<>
<button onClick={addItem}>Add Item</button>
<ul>
{items.map(item => (
<li key={item.id}>
{item.text}
<input type="text" />
</li>
))}
</ul>
</>
);
}
이제 새 항목을 추가하거나 목록을 재정렬해도 React가 각 항목을 정확하게 추적할 수 있습니다.
결론
축하합니다! React에서 키의 힘을 해제했습니다. 키는 목록 항목에 이름 태그를 달아주는 것과 같아서, React가 특정 항목을 추적하는 데 도움을 줍니다.
이제 우리가 배운 내용을 요약해 보겠습니다:
개념 | 설명 |
---|---|
키 | React 목록 항목의 특별한 문자열 속성 |
목적 | 목록의 변경 사항을 효율적으로 식별 |
가장 좋은 관행 | 안정적이고 고유한 식별자를 키로 사용 |
인덱스를 키로 사용 | 정적이고 변경되지 않는 목록에만 사용 |
이점 | 성능 향상과 컴포넌트 상태 유지 |
키를 계속 연습하면, 곧 동적인 React 애플리케이션을 효율적으로 만들 수 있을 것입니다. 행복하게 코딩하세요, React의 세상에서 각 항목은 고유한 키를 가지고 있어야 합니다!
Credits: Image by storyset