React

[React] 배열 렌더링 시 key prop을 사용하는 이유

emmaOH! 2024. 6. 28. 10:31

🔑 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>
  );
}

이 코드를 실행하면 화면에 리스트가 잘 출력되지만, 콘솔창에는 리스트의 각 항목에 키를 넣어야 한다는 경고가 출력됩니다.

(위의 코드가 아닌 다른 파일을 실행한 것이므로 경고 문구만 봐주시면 됩니다.) 

key를 넣지 않았을 때 뜨는 경고

 


 

더 간단한 예시는 다음과 같습니다.

아래와 같이 사과, 망고, 포도가 들어있던 배열에서 망고가 사라지고 사과와 포도만 남았습니다.

사과, 망고, 포도가 들어있던 배열

i) 대부분의 사람들은 이것을 보고 '망고가 삭제되었구나'라고 생각하지만,

ii) 사실은 포도라는 요소가 삭제되고, 망고가 -> 포도로 바뀌었을 수도 있습니다.

각 요소마다 고유한 키를 사용하지 않는다면 어떤 요소에 무슨 동작을 한 건지 알 수 없습니다.

망고가 삭제된 경우 vs 포도가 삭제되고 망고가 포도로 바뀐 경우

이때 키를 사용하면 어떨까요?

키를 사용한 경우

2라는 키 값을 가진 망고가 삭제되고, 키 1의 사과와 키 3을 가진 포도만 남게 된 경우인 것을 확실히 알 수 있습니다.

 


읽어주셔서 감사합니다:)