[에러 일지] 리스트에 key 값을 부여했는데도 발생하는 "key" prop 에러 해결하기 (<>에 key 적용하기)

uxolrv·2023년 3월 15일
0
post-thumbnail

❗️ 문제 : Warning: Each child in a list should have a unique "key" prop.

메인 프로젝트 상세페이지에서 위와 같이 리스트의 각 자식들이 유니크한 key prop을 가져야 한다는 에러가 발생하였다.

상세페이지에서 map을 적용하여 렌더링되고 있는 리스트들은 review, talk, talk comment 총 3가지이다.

정말 요상한 것은!!! 이미 각 리스트에게 key로 각 리스트의 id를 넘겨주고 있었는데도 해당 에러가 발생한다는 것이다 😢








🔎 시도 (실패)

리액트 공식 문서에 따르면 키는 형제 사이에서만 고유하면 된다고 한다.

review는 다른 태그로 감싸져 있어서 괜찮지만, talktalk comment는 같은 레벨에 있는 형제 관계인 것을 확인했다!



lists.reviews.data.map((review) =>
  <DetailReviewList
    key={review.reviewId}
    ...
  />
);

...

lists.talks.data.map((talk) => (
  <>
    <DetailTalkList
      key={talk.talkId}
      ...
    />
    {talk.talkComments &&
      talk.talkComments.map((retalk) => {
        <DetailTalkList
          // 📌 적용한 부분!
          key={`${retalk.talkCommentId.toString()}-retalk`}
          ...
          />;
      })}
  </>
));

그래서 talktalkCommentid가 겹쳐서 에러가 날 수도 있겠구나! 싶어서 talkCommentId 뒤에 retalk라는 문자를 붙여 유니크한 key로 만들었다.

그러나... 여전히 에러가 사라지지 않아 콘솔에 data를 찍어 확인해보니, 에러가 발생하는 해당 페이지에서는 애초에 talktalkCommentid가 중복되는 부분이 없었다. 😢








💡 원인

lists.talks.data.map((talk) => (
  <> // 📌 문제!!
    <DetailTalkList
      key={talk.talkId}
      ...
    />
    {talk.talkComments &&
      talk.talkComments.map((retalk) => {
        <DetailTalkList 
          key={`${retalk.talkCommentId.toString()}-retalk`}
          ...
          />;
      })}
  </> // 📌 문제!!
));

해당 talktalkComments가 있을 경우에는 2개 이상의 리스트가 렌더링되기 때문에, 이 리스트들을 감싸주기 위해 <>...</>를 사용했었는데 바로 이 래퍼 태그에 key prop이 없던 것이 문제였다!



그러나 <key={...}> 로는 key를 전달할 수가 없어서 리액트 공식 문서를 확인해보니 명시적인 <Fragment> 태그를 사용하면 key를 전달할 수 있음을 알게 되었다!

이게 새로운 공식 문서에 나와있다니.. 나 같은 사람이 많았나 싶다 😂








✨ 해결

import { Fragment } from 'react';

lists.talks.data.map((talk) => (
  <Fragment key={talk.talkId}>
    <DetailTalkList
      key={talk.talkId}
      ...
    />
    {talk.talkComments &&
      talk.talkComments.map((retalk) => {
        <DetailTalkList 
          key={retalk.talkCommentId}
          ...
          />;
      })}
  </Fragment>
));

드디어 에러를 해결했다!!!!!!1 🥳

React.Fragment를 사용하기 위해 구조분해할당으로 Fragmentimport 해온 후, Fragment의 축약 버전으로 작성했던 <><Fragment>로 바꿔, key를 적용하였다!








메인 프로젝트 진행하던 당시부터 지금까지 계에에속 신경쓰였었는데 진작에 공식 문서 좀 볼 걸 그랬다... 😢
심지어 <> 이 친구가 <React.Fragment>의 단축 문법이라는 것도 처음 알았다...

그래도 옛날 같았으면 에러를 공식 문서에서 찾아서 해결할 생각은 하지도 못했을텐데
최근에는 잘 안되거나, 에러가 발생하면 공식문서를 가장 먼저 보게 되는 것 같다
역시 공식문서가 괜히 공식이 아니구나~




참고: 리액트 공식문서

profile
안녕하세연🙋 프론트엔드 개발자입니다

0개의 댓글