본 포스트는 React에서 배열을 다룰 때 발생할 수 있는 오류인 Each child in a list should have a unique "key" prop 오류 원인 및 해결 방법에 대해 설명합니다.
React로 개발할 때 목록 구현을 위해 보통 아래와 같이 개발합니다.
const NewsRow = ({title, pubDate, description}) => {
return (
<li>
<div className="title">
<a href="#" dangerouslySetInnerHTML={{__html: title}}></a>
</div>
<div className="cont">
<span className="date">{pubDate}</span>
<span dangerouslySetInnerHTML={{__html: description}} />
</div>
</li>
);
};
...
articles.map((v, inx) => {
return <NewsRow {...v} />
})
...
위와 같이 개발하면 UI에는 목록이 표시되지만 브라우저 콘솔 로그에 아래와 같은 오류가 나타납니다.
react.development.js:217 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `ListView`. See https://reactjs.org/link/warning-keys for more information.
at NewsRow (webpack://searchNaverApi/./src/component/listview.component.jsx?:37:20)
at ListView (webpack://searchNaverApi/./src/component/listview.component.jsx?:91:66)
at div
at RecoilRoot_INTERNAL (webpack://searchNaverApi/./node_modules/recoil/es/index.js?:4225:3)
at RecoilRoot (webpack://searchNaverApi/./node_modules/recoil/es/index.js?:4391:5)
at App
React는 사용자가 개발한 컴포넌트의 상태가 변경되면 Re-Rendering을 하는데, 컴포넌트와 DOM의 Element 간의 관계를 생성할 때 "key" prop을 사용합니다. 따라서 key prop을 설정하지 않았다면 최초 1회는 문제 없이 Rendering을 했다 하더라도, 상태가 변경됨에 따라 오류들이 발생할 수 있습니다.
가장 간단한 해결책은 배열 요소의 인덱스를 넘기는 방법입니다.
articles.map((v, inx) => {
return <NewsRow key={inx} {...v} />
})
하지만 위 코드는 샘플에서나 사용할 뿐, 실제로는 되도록 해당 배열에서 고유한 값을 사용해야 합니다. JavaScript의 배열은 동적으로 변경이 일어날 수 있으므로 인덱스 값은 언제든지 변할 수 있습니다. 위와 같은 경우의 예라면 뉴스의 게시물 번호 등을 사용해서 해당 Row에서 변하지 않는 고유한 값을 사용하는게 가장 좋습니다.
articles.map((v, inx) => {
return <NewsRow key={v.articleId} {...v} />
})
이런 형태로 설정하고 나면 브라우저의 콘솔에 오류 로그가 사라졌음을 확인할 수 있습니다.
300x250