- 리액트 공식문서 기반으로 이해한 내용을 정리한 포스트 입니다. -
key 속성은 React에서 동적으로 생성되는 엘리먼트 목록을 렌더링할 때 사용되는 중요한 속성이다. 여기서 몇 가지 주요 용도를 살펴보자.
유일성 보장
React에서는 동적으로 생성되는 엘리먼트에 `key` 속성을 제공해야 한다. 이는 React가 각 엘리먼트의 유일성을 보장하고, 어떤 엘리먼트가 추가, 수정, 또는 삭제되었는지 정확히 파악할 수 있게 해준다.
재사용 가능한 상태 유지
`key`는 리액트가 어떤 컴포넌트를 다시 렌더링해야 하는지 식별하는 데에도 사용된다. 키가 변경되면 리액트는 해당 키에 해당하는 컴포넌트를 다시 만들고 상태를 유지한다.
성능 최적화
효율적인 업데이트와 재렌더링을 위해 key가 필요하다. 예를 들어 배열에서 특정 아이템을 삭제하고 새 아이템을 추가하는 경우, key를 사용하면 리액트가 변경된 아이템만 업데이트하고 다시 렌더링할 수 있다.
예를 들어, 다음과 같이 배열을 매핑하여 엘리먼트를 생성하는 경우
const items = [1, 2, 3];
const itemList = items.map((item) => (
<div key={item}>
Item {item}
</div>
));
위의 예제에서 `key={item}`는 각 아이템을 유일하게 식별하는 데에 사용되고, React는 이를 통해 각각의 엘리먼트를 정확히 관리할 수 있다.
키는 목록에서만 사용되는 것이 아니다.
이는 앞서 2 번에서 재사용 가능한 상태 유지에 대한 내용과 이어지는 부분이다.
보통 key 를 활용할 때 앞서 예시와 같이 li 와 같은 목록 형태에서 자주 활용한다 .하지만 리액트에서 key 는 동일한 위치에서 렌더링 되는 동일한 이름의 컴포넌트를 서로 다른 컴포넌트로서 식별하고자 할 때 활용할 수 있다.
예를 들어, 아래 코드를 살펴보자.
import { useState } from 'react';
export default function Scoreboard() {
const [isPlayerA, setIsPlayerA] = useState(true);
return (
<div>
{isPlayerA ? (
<Counter key="Taylor" person="Taylor" />
) : (
<Counter key="Sarah" person="Sarah" />
)}
<button onClick={() => {
setIsPlayerA(!isPlayerA);
}}>
Next player!
</button>
</div>
);
}
위 코드에서 Counter 라는 컴포넌트가 isPlayerA 라는 boolean 값(상태)에 따라서 key 를 각각 Taylor 와 Sarah 를 전달하고 있다. 만일 키를 별도로 전달해주지 않는다면, 리액트는 Counter 컴포넌트를 동일한 컴포넌트로 간주하고 리렌더링 시 두 컴포넌트를 모두 초기화 시키지만, 식별 가능한 키를 제공해주게 되면, 전자의 Counter 컴포넌트가 특정 조건에 의해 리렌더링 되어 상태가 초기화되더라도, 후자의 Counter 는 별도의 상태를 가지는 컴포넌트로 취급 되기 때문에 초기화되지 않고 기존 상태를 유지할 수 있다.
Key는 변동 가능하면 안 된다(배열 index는 절대 금지).
앞서 Key 의 용도와 중요성을 언급했는데, 이와 반대되는 문제를 일으킬 수 있는 사용법도 존재한다. Key 를 입력하지 않거나, 입력하더라도 map 과 같은 순회가능한 메서드가 기본으로 제공하는 index 값을 Key 로 지정하는 경우이다.
한편으로는 고유한 식별자로 사용할 키가 없어서 인덱스를 불가피 하게 사용할 수는 있겠지만, 이는 임시방편일 뿐이다. 언제가 되었든 꼭 대체되어야 한다.
본론으로 와서 key 를 올바르게 사용하지 않은 경우 문제점은 앞서 언급한 중요성의 반대로 정리할 수 있을 것 같다.
유일성 보장이 어려움
배열의 인덱스는 해당 아이템의 위치를 나타내지만, 유일성을 보장하지는 않는다. 특히 배열이 동적으로 변경되거나 정렬되는 경우에는 같은 인덱스의 키가 변경될 수 있어 문제가 발생할 수 있다.
성능 이슈
배열의 아이템이 추가 또는 제거될 때 인덱스를 키로 사용하면 React가 모든 엘리먼트를 비교해야 하므로 성능에 부담을 줄 수 있다. 이는 렌더링 최적화와 관련된 문제로, 배열이 크고 동적으로 변경되는 경우 더욱 두드러질 수 있다.
컴포넌트 재사용 문제
인덱스를 키로 사용하면 배열의 아이템이 변경되거나 이동할 때 문제가 발생할 수 있다. 새로운 아이템이 추가되거나 기존 아이템이 제거되면 인덱스가 변경되어 React가 컴포넌트를 재사용하는 데에 문제가 생길 수 있다.
따라서 특히 동적으로 변경되는 배열의 엘리먼트를 렌더링할 때는 고유하고 예측 가능한 키를 사용하는 것이 좋다. 아이템의 고유한 식별자를 키로 사용하는 것이 일반적으로 좋은 방법이다. 예를 들어, 참여자 명단이라는 배열이 있다면, 각 참여자의 참가번호 혹은 주민등록번호 등과 같이 중복이 허용되지 않는 값을 활용할 수 있을 것이다.
'리액트' 카테고리의 다른 글
[react ] Jotai, Recoil, Zustand, Valtio | Jotai (1) (1) | 2023.12.10 |
---|---|
[React.v18 ] useTransition 과 논블로킹 (4) | 2023.11.26 |
[react] 리액트에서 상태에 대한 정리(3) - 배열 (0) | 2023.11.08 |
[react] 리액트에서 상태에 대한 정리(2) - 객체 (0) | 2023.11.07 |
[react] 리액트에서 상태에 대한 정리(1) - 상태 (0) | 2023.11.06 |