[React] 리액트에서 map 함수 적용시 key props 를 부여하는 이유
![[React] 리액트에서 map 함수 적용시 key props 를 부여하는 이유](/assets/img/reactlogo.png)
뻔한 문서적 이론은 인터넷에 널려있습니다. 그렇기에 저는 그러한 포스팅은 지양하며,
단순히 어떠한 것인지 이해하기 쉬운 형태로 작성했음을 알려드립니다.
음.. 받아온 state 값을 가지고 리스트를 만들어 뿌려 볼까?
투닥투닥.. .. …. 띠용?~ Warning! Waring! 잉? 왜이래? 고유한 키값이 있어야 한다고???
Warning 메시지 뿜뿜
우리가 리액트를 배우고 API나 state로 받은 값을 리스트로 만들어 뿌리는 코드를 작성할 때
항상 마주하는 경고 메시지가 있다. 바로 리스트에는 고유한 ‘Key’를 부여하라는 메시지
아! 그렇다고 페이지가 랜더링이 안되는 것은 아니다. 잘된다!
- 아래의 화면은 input에서 value 값을 받아와 comment로 props 를 넘겨주고
map 으로 리스트를 만드는 코드를 작성했다.
위의 코드를 작성한 이미지
- 그리고 나서 저장을 하면 랜더링에는 문제가 없지만 이와 같은 경고가 콘솔 창에 나타난다.
(vscode eslint 덕분에 vscode에서도 알려준다)
그만 보고 싶어요 노란글씨 빨간글씨ㅠㅠ
경고의 이유
이미 콘솔 창에도 잘 쓰여있지만, 각각의 리스트에 키값을 부여하지 않아 생긴 warning이다.
리액트 공식 문서에는 key에 대해 다음과 같이 명시하고 있다.
Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다.
Key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.
즉 어떠한 요소에 변화가 일어나면(추가, 삭제가 되었든 간에) 그것을 알아차리기 위해 필요한 것이다.
리액트는 굳이 쓸데없는 렌더링을 피하기 위해 필요한 부분, 변경사항이 있는 부분만 리렌더링을 한다.
어떠한 배열이나 리스트에 변화가 일어나면 그 배열이나 리스트 전부 다 리렌더링을 하는 것이 아니라
변화가 일어난 것에 대해서만 리렌더링을 하기 위해 변화가 일어난 부분이 어떠한 부분인지 식별하기 위해
각각의 고유한 ‘key’ 값이 필요한 이유이다.
주의 사항
다음은 공식문서에 있는 내용이다.
렌더링 한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 항목의 인덱스를 key로 사용할 수 있습니다.
다르게 말하면 웬만하면 key 값으로 인덱스를 사용하지 말라는 것이다. 받아온 API에 ID 값이 없는 이상..
처음의 작성한 코드를 보면 난 인덱스로 키값을 사용하고 있다. 해당 state에 ID 값이 없었기 때문
그렇다면 이유는?
고유한 key 값을 가진 요소가 변화가 되면 즉시 어떤 것이 변화가 되어 리렌더링을 할 것인지 알 수 있지만,
인덱스 값은 요소의 삭제, 변경으로 인해 순서가 바뀌면 인덱스 값도 같이 변경이 된다.
그렇기 때문에 변화된 요소만 렌더링 하는 리액트의 장점을 이용하지 못하는 것이다.
잘못된 사용방법
다음은 공식 문서에 나온 잘못된 사용방법이다.
- 리스트의 부모 아이템에 key 값을 주지 말것
// file: "ListItem.js"
// 잘못된 사용방법
const ListItem = (props) => {
return (
<li key={props.id}>
{props.content}
</li>
)
}
// 올바른 사용방법
const ItemList = (props) => {
const item = props.content;
const listItem = item.map((it)=>{
<li key={props.id}>{it}<li>
})
return(
<ul>
{listITem}
</ul>
)
}
// 둘 의 차이점은 부모요소에 바로 key값을 주느냐 자식 요소에 키값을 주느냐의 차이
Key는 형제 사이에서는 고유한 값이어야 한다.
map 함수를 JSX에 포함시킬 것
마무리
이처럼 리액트가 각각의 변화된 요소를 파악하여 정확한 리렌더링을 할 수 있도록 key값을 잘 주도록 하자!