본문 바로가기

React

React - 배열을 렌더링시 key를 써야 하는 이유

key를 사용하지 않은 경우

처음 배열 : ['강아지', '고양이', '햄스터']
바뀐 배열 : ['강아지', '햄스터']

처음 배열을 렌더링 후, 바뀐배열로 데이터가 바뀌었다면, react는 해당 배열에서

  1. 두 번째 요소가 삭제된것인지?
  2. 세 번째 요소가 삭제되고, 두 번째 요소가 '햄스터'로 바뀐것인지?

등의 많은 경우 중 하나로 특정할 수 없다.

 

key를 사용한 경우

처음 배열 : [{key:1, name:'강아지'}, {key:2, name:'고양이'}, {key:3, '햄스터'}]
바뀐 배열 : [{key:1, name:'강아지'}, {key:3, '햄스터'}]

key값을 통해, 1과 3은 그대로 존재하고, 2가 삭제되었다는 것을 알 수 있다.

 

 

코드로 확인해보기

import React from 'react';
import './ReviewList.css';

function ReviewListItem({ item, onDelete }) {
  const handleDeleteClick = () => {
    onDelete(item.id);
  };
  
  return (
      <div>
        <h1>{item.title}</h1>
        <p>{item.content}</p>
      </div>
  );
}

function ReviewList({ items, onDelete }) {
  return (
    <ul>
      {items.map((item) => (
        <li>
          <ReviewListItem item={item} onDelete={onDelete}/>
          <input/>
        </li>
      ))}
    </ul>
  );
}
export default ReviewList;
  • 위와 같은 코드가 있을 때, 실행해보면 일단 에러가 발생한다.

  • 그리고, ReviewList 컴포넌트에서 렌더링 된 li중에 세번째에 있는  li의 input에 값을 입력하고, 윗 쪽 li를 삭제해보면, input에 입력한 값이 index에 종속되어 계속 세번째 input에 값이 들어있는 것을 확인할 수 있다.
  • 간단히 예를들면 아래와 같이 된다.

  • 이것은, map메서드에 존재하는 index파라미터를 key로 준 것과 같은 동작을 한다.
function ReviewList({ items, onDelete }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>
          <ReviewListItem item={item} onDelete={onDelete}/>
          <input/>
        </li>
      ))}
    </ul>
  );
}
  • 위와 같이 작성한 것과 마찬가지라는 뜻.
  • index는 데이터가 추가/삭제됨에 따라 계속해서 변화하기때문에 데이터를 특정할 수 없다.
function ReviewList({ items, onDelete }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <ReviewListItem item={item} onDelete={onDelete}/>
          <input/>
        </li>
      ))}
    </ul>
  );
}
  • 위와 같이 데이터를 특정할 수 있는 값을 key로 주면 원하는데로 동작하는 것을 확인할 수 있다.