리스트와 Key

</>·2022년 4월 11일
3
post-thumbnail

목표

  • 리스트와 Key에 대해 알아보기

8. 리스트와 Key

8-1. 여러 개의 엘리먼트 렌더링

  • li 엘리먼트 모음을 만들고 중괄호 { } 를 활용해 JSX에 포함시킬 수 있다.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => 
  <li>{number}</li>
 );
  • 그 후, list 배열을 ul 엘리먼트에 포함하고 DOM에 렌더링한다.
ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

8-2. 기본 리스트 컴포넌트

  • 위의 코드를 컴포넌트화 시키면 다음과 같다.
function NumberList({ numbers }) {
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
                                
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
  • numbers 배열을 받아서 순서 없는 엘리먼트 리스트를 출력하는데 문제가 없지만 콘솔을 확인해보면 리스트 각 항목에 key를 넣어야 한다는 경고가 표시된다.
  • 참고로 경고가 표시되어도 리액트가 알아서 index를 쓰기 때문에 문제 없이 사용 가능하다.


8-3. Key

  • Key는 리액트가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는 역할을 한다.
  • 또한, 엘리먼트에 안정적인 고유성을 부여하는 역할을 수행한다.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>{number}</li>
);
  • Key를 선택하는 가장 좋은 방법은 리스트의 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것이다.
  • 대부분 데이터의 ID를 Key로 사용한다.

✏️ 참고

  • 렌더링 한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 항목의 인덱스를 Key로 사용할 수 있다.
const listItems = numbers.map((number, index) =>
  <li key={index.toString()}>{number}</li>
);
  • 하지만, 항목의 순서가 바뀔 위험이 있으므로 인덱스를 key로 사용하는 것은 권장하지 않는다.

8-4. Key로 컴포넌트 추출하기

  • Key는 리스트 즉, map() 함수 내부에 있는 엘리먼트에 넣어주는 것이 좋다. 예를 들어,
export default function List() {
  const todos = [
    {
      id: 1,
      do: "go to hospital"
    },
    { id: 2, do: "go to cafe" },
    { id: 3, do: "eating dinner" }
  ];

  const Item = (props) => {
    return <li key={props.id}>{props.do}</li>;
  };
  const todoList = todos.map((todo) => <Item {...todo} />);
  return <ul>{todoList}</ul>;
}
  • map 함수 내부가 아닌 컴포넌트에 Key를 넣어주면 출력에는 문제가 없지만 콘솔을 확인해보면 아까 봤던 key를 넣어야 한다는 경고가 표시된다.

export default function List() {
  const todos = [
    {
      id: 1,
      do: "go to hospital"
    },
    { id: 2, do: "go to cafe" },
    { id: 3, do: "eating dinner" }
  ];

  const Item = (props) => {
    return <li>{props.do}</li>;
  };
  const todoList = todos.map((todo) => <Item key={props.id} {...todo} />);
  return <ul>{todoList}</ul>;
}
  • 이번에는 map 함수 내부에 있는 컴포넌트에 Key를 넣어주면 콘솔에 에러가 뜨지 않고 잘 출력된다.

8-5. Key는 형제 사이에서만 고유한 값이어야 한다.

  • 위의 코드에서 Key를 자식 컴포넌트로 넘겨주었다.
  • 그렇다면 자식 컴포넌트는 Key 값을 알 수 있을까?
export default function List() {
  const todos = [
    {
      id: 1,
      do: "go to hospital"
    },
    { id: 2, do: "go to cafe" },
    { id: 3, do: "eating dinner" }
  ];

  const Item = (props) => {
    return (
      <li>
        {props.key}
        {props.do}
      </li>
    );
  };
  const todoList = todos.map((todo) => <Item key={todo.id} {...todo} />);
  return <ul>{todoList}</ul>;
}
  • props.key를 추가해서 위 코드를 실행해보면 다음과 같은 에러가 발생한다.
  • 따라서, Key는 자식 컴포넌트로 전달되지 않으므로 key와 동일한 값이 필요하다면 다른 이름의 props로 넘겨주어야 한다.
const todoList = todos.map((todo) => <Item key={todo.id} id={todo.id} do={todo.do} />);

출처

profile
개발자가 되고 싶은 개발자

0개의 댓글