Key가 필요한 이유

Happhee·2022년 3월 12일
0

💙  React 💙

목록 보기
3/18

key란?

React안에서 변경, 추가 , 제거되는 항목을 식별하기 위해 필요한 속성이다.

엘리먼트 리스트를 만들 때, 포함해야하는 특수한 문자열 어트리뷰트라고 생각하면 된다.

엘리먼트 리스트의 예제 코드를 살펴보자 👇

const numbers = [1, 2, 3, 4, 5];
const listNumbers = numbers.map((number)=>
  <li>{number}</li>
);

ReactDOM.render(
  <ul>{listNumbers}</ul>,
  document.getElementById('root')
);

위와 같은 방식으로 여러 개의 <li> 를 한 번에 렌더링해줄 때, key의 속성이 들어가지 않으면 경고문구가 출력된다.


key값 지정하는 방법

key값은 고유하게 식별 가능한 문자열을 사용해야 한다.

규칙 1

key는 형제 사이에서만 고유한 값이어야 한다.

즉, 전체 범위에서 고유할 필요는 없다.
따라서 두 개의 다른 배열을 만들 때에는 동일한 key값을 사용할 수 있다.

예제 코드로 이해해보자. 👇

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);

위의 코드를 살펴보면, sidebar의 licontent의 div key가 id로 같다는 것을 확인할 수 있다.

이것이 가능한 이유는 두 개의 요소가 형제 사이가 아니기 때문이다.
때문에, 우리는 두 개의 다른 배열을 생성할 때, 동일한 키를 사용할 수 있다는 것을 명심해야 한다.

규칙 2

만약, <ul>안에 배열을 생성할 경우, 컴포넌트에 key를 지정해야 한다.

컴포넌트 내부의 <li>에 key를 지정하는 것은 무의미하다.

예제 코드로 이해해보자. 👇

  • 잘못된 방식으로 작성된 코드이다.
// wrong
function ListItem(props) {
  const value = props.value;
  return (
    // 이곳에 key를 지정하면 무의미하다.
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function ListNumber(props) {
  const numbers = props.numbers;
  const listNumbers = numbers.map((number) =>
    // 배열의 ListItem 엘리먼트가 key를 가져야 한다.
    <ListItem value={number} />
  );
  return (
    <ul>
      {listNumbers}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <ListNumber numbers={numbers} />,
  document.getElementById('root')
);

ListNumber를 불러올 때, <ul>의 하위 요소들은 <ListItem>이다.
따라서, <ListItem>자체의 속성으로 key를 가지고 있어야 하기에 위의 방식은 오류를 나타낸다.

이를 해결한 최종 코드는 다음과 같다.👇

// right
function ListItem(props) {
  return <li>{props.value}</li>;
}

function ListNumber(props) {
  const numbers = props.numbers;
  const listNumbers = numbers.map((number) =>
    <ListItem key={number.toString()} value={number} />
  );
  return (
    <ul>
      {listNumbers}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <ListNumber numbers={numbers} />,
  document.getElementById('root')
);

📚 학습할 때, 참고한 자료 📚

profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글