🔑 key란
키는 리액트가 어떤 항목을 변경하거나 추가 또는 삭제할지 식별하는 것을 돕습니다.
키는 각 요소에 고유성을 부여하기 위해 배열 내부의 요소에 지정해야 하고, 그 값은 변하지 않아야 합니다.
전체 범위에서 고유할 필요는 없고, 형제 요소들 사이에서만 고유한 값이면 가능합니다.
따라서 대부분의 경우, 데이터의 id를 키로 지정하여 사용합니다.
function NumberList({ numbers }) {
const listItems = numbers.map((number) =>
<li key={number.id}>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
렌더링 한 항목에 대한 안정적인 id가 없거나 명시적으로 키를 지정하지 않으면, 대안으로 요소의 인덱스를 key로 사용할 수 있습니다.(리액트가 알아서 인덱스를 키로 사용)
그러나 인덱스는 요소의 순서에 따라 변경될 우려가 있기 때문에 권장되지 않습니다.(요소가 불변하면 인덱스를 사용해도 상관없음)
🔑 key 없이 렌더링 하는 경우
아래는 숫자가 담긴 배열을 받아 map() 메서드를 통해 순서가 없는 리스트로 출력하는 예시입니다.
function NumberList({ numbers }) {
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
이 코드를 실행하면 화면에 리스트가 잘 출력되지만, 콘솔창에는 리스트의 각 항목에 키를 넣어야 한다는 경고가 출력됩니다.
(위의 코드가 아닌 다른 파일을 실행한 것이므로 경고 문구만 봐주시면 됩니다.)
더 간단한 예시는 다음과 같습니다.
아래와 같이 사과, 망고, 포도가 들어있던 배열에서 망고가 사라지고 사과와 포도만 남았습니다.
i) 대부분의 사람들은 이것을 보고 '망고가 삭제되었구나'라고 생각하지만,
ii) 사실은 포도라는 요소가 삭제되고, 망고가 -> 포도로 바뀌었을 수도 있습니다.
각 요소마다 고유한 키를 사용하지 않는다면 어떤 요소에 무슨 동작을 한 건지 알 수 없습니다.
이때 키를 사용하면 어떨까요?
2라는 키 값을 가진 망고가 삭제되고, 키 1의 사과와 키 3을 가진 포도만 남게 된 경우인 것을 확실히 알 수 있습니다.
읽어주셔서 감사합니다:)