❗️Error/오류를 해결하자!

Each child in a list should have a unique "key" prop.

hellohailie 2022. 6. 27. 19:58

Each child in a list should have a unique "key" prop.

 

오류의 원인

➥ 간단히 배열의 길이를 체크하고 이미 렌더링된 아이템의 수만 확인한다. 리액트에게는 각각의 아이템들이 모두 비슷해 보인다. 그래서 새로운 아이템이 어느 위치에 추가되어야 하는지 모르기 때문에 오류가 나타났다. 

 

 

"key" prop이 없다면

리액트는 새로운 아이템을 div 목록에 있는 마지막 아이템으로 렌더링하고 모든 아이템을 업데이트해서 컨텐츠를 교체한다. 

 

이 방법은 별로 좋지 않은데, 그 이유는 리액트에게 이 모든 아이템들이 비슷해 보이고 배열만 전보다 더 길어진 것을 보았기 때문에 벌어진 일이다. 그래서 추가로 div를 넣어 렌더링해서 끝부분에 추가한 것이다. 그런 다음 모든 아이템들을 지나면서 배열에 있는 컨텐츠와 다시 일치시키기 위해 안에 있는 컨텐츠를 업데이트 해준다. 

=> 보여지는 것에는 문제가 없지만, 성능 측면에서 보면 좋지 않다. 왜냐면 모든 목록을  체크해서 업데이트 해야하고, 버그를 만들 수도 있기 때문이다.  (유저가 추가한 아이템이  특정 state를 가지고 있었다면 이 새 아이템은 이전 아이템을 덮어쓸 수도 있다. )

 

 

 

오류 해결

아이템 목록이 출력되는 곳에 가서 (map메소드가 있는 곳) 고유한 key props를 추가한다. 

이렇게 생각하면 쉽다. 👉 목록의 아이템을 mapping할 때는 항상 key를 추가해야 한다. 

 

추가공부

👇key를  추가해야하는 이유👇

2022.07.27 - [React] - 리액트의 가상 DOM, React가 DOM 트리를 탐색하는 방법, key 값을 설정하는 이유

 

리액트의 가상 DOM, React가 DOM 트리를 탐색하는 방법, key 값을 설정하는 이유

리액트에는 virtual DOM이라고 하는 가상의 DOM 객체가 있다. 이 가상의 DOM 객체는 실제 DOM의 사본 같은 개념으로, 리액트는 실제 DOM 객체에 접근하여 조작하는 대신 이 가상의 DOM 객체에 접근하여

shinystarforever.tistory.com

 

 

 방법 1. data에 고유한 값이 있을 때

const DUMMY_EXPENSES = [
  {
    id: "e1",
    title: "Toilet Paper",
    amount: 94.12,
    date: new Date(2020, 7, 14),
  },
  { id: "e2", title: "New TV", amount: 799.49, date: new Date(2021, 2, 12) },
  {
    id: "e3",
    title: "Car Insurance",
    amount: 294.67,
    date: new Date(2021, 2, 28),
  },
  {
    id: "e4",
    title: "New Desk (Wooden)",
    amount: 450,
    date: new Date(2021, 5, 12),
  },
];

➥ 위의 data에는 Id라는 고유한 값이 있기 때문에 key를 나열할 data에서 id를 불러오면 된다. 

 

{props.items.map((expense) => (
          <ExpenseItem
            key={expense.id}
            title={expense.title}
            amount={expense.amount}
            date={expense.date}
          />
        ))}

 

 방법 2. data에 고유한 id 값이 없을 때

map의 두 번째 인자를 사용하면 된다. => 그다지 장려되는 방법은 아니라고 함.

(1. 특정한 아이템에 대한 인덱스가 항상 똑같기도 하고, 2. 아이템 컨텐츠에 직접적으로 첨부된 것이 아니기 때문에 버그를 발생시킬 수도 있기 때문이다!)

 

어떤 원시값도 고유 식별자로 사용할 수 있고, 어떤 숫자나 문자열도 고유 식별자가 될 수 있다.  

 

        {props.items.map((expense, index) => (
          <ExpenseItem
            key={index}
            title={expense.title}
            amount={expense.amount}
            date={expense.date}
          />
        ))}

 

 

 

😃 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장에 큰 도움이 됩니다🤓