에러해결기

Warning: Each child in a list should have a unique "key" prop. (고유한 key값을 넣지 않았을 때)

hihiha2 2023. 4. 21. 15:11

 

todo와 같이 crud를 만드면서 create기능을 구현할때도 만났던 에러이다.

create를 할때는 새로운 키값을 넣어줘야하기 때문에 uuid라이브러리를 이용해서 이러한 에러를 해결했다.

 

 

 

uuid를 사용하는 이유사용법직접 블로그에 정리해두었다.

 

리액트 uuid 설치 (리액트 고유id, 고유key 사용이유)

uuid란 리액트에서 사용하는 라이브러리로서, 고유한 id값을 자동으로 추가해줘서 편리하다. 1. 사용법 1️⃣ install npm install uuid npm을 사용하면 위와같은 코드를, yarn을 사용하면 yarn add uuid 를 통

hihiha2.tistory.com

 

 

하지만 이번에는 같은 오류더라도 추가하기 기능이 아니라, 이미 존재하는 open api를 받아오면서 고유한 key값을 넣어줘야 하는 에러여서 다른 해결법을 사용하였다.

 

 

🔍 원인

고유한 key값을 부여해주지 않아서.

 

- 고유한 key값을 부여해야 하는 이유

고유한 key를 부여해줘야하는 이유는 배열의 효율적인 관리를 위해서이다.

배열에는 각각의 순서에 따라서 [0], [1], [2], [3], [4] 와 같이 순서가 있다.

그런데 이것에 고유한 id나 key값을 주지 않으면, 하나만 수정해도 전체의 순서가 밀리면서 변경되면서 업데이트시 비효율을 초래할 수 있다.

 

하지만, 고유한 id가 있다면 배열중 하나가 변경이 되더라도 그 고유한 id값을 기억해서 그 부분만 업데이트가 가능해 효율적인 관리가 가능하다.

(또한 이렇게 해야 콘솔창에 에러가 발생하지 않는다)

 

 

 

❌ 비효율적 해결법 ❌

index를 key값으로 넣기.

➡️ Index를 사용하면 항목의 순서변경시 key 또한 변경되고 state관리가 어려워진다.

 

 <div className="container">
          {bookData?.slice(offset, offset + limit).map((books,i) => {
            if i
              books.volumeInfo?.imageLinks?.smallThumbnail &&
              books.saleInfo?.listPrice?.amount &&
              books.volumeInfo?.title
            ) {
              return (
                <BookCard
                  key={i}
                  books={books}
                  setSelectedBook={setSelectedBook}
                />
              );
            }
          })}
          {selectedBook && (
            <BookDetailModal
              selectedBook={selectedBook}
              onClose={handleCloseBookDetailModal}
            />
          )}
        </div>

 

 

✅ 해결

key={item.id}

key값에 받아오는값.id를 넣어준다.

 

 

 

🙆‍♂️ 수정한 코드 🙆‍♂️

 

<main>
<div className="container">
{bookData?.slice(offset, offset + limit).map((books) => {
if (
books.volumeInfo?.imageLinks?.smallThumbnail &&
books.saleInfo?.listPrice?.amount &&
books.volumeInfo?.title
) {
return (
<BookCard
key={books.id}
books={books}
setSelectedBook={setSelectedBook}
/>
);
}
})}
{selectedBook && (
<BookDetailModal
selectedBook={selectedBook}
onClose={handleCloseBookDetailModal}
/>
)}
</div>
</main>

기존코드에서는 key={books.id}가 없었는데 추가해 주었다.

 

 

🕵️‍♀️ 느낀점

index를 통해서 해결하는 방법도 있지만, state의 관리를 위해서 다른 방식을 사용하는 것이 좋다는 것이 흥미로웠다.

같은 문제가 발생해도 해결법은 여러개이고 더 나은 상태관리와 렌더링관리 방법이 있는것같아서 이런 부분을 더 공부하고 싶다.

 

 

참고

https://sambalim.tistory.com/150