key를 알아보기 전에 map함수 사용법에 대해서 간단히 알고 가보자
const IterationSample = ()=>{
const names = ['눈사람', '얼음', '눈', '바람'];
const nameList = names.map(name=><li>{name}</li>);
return <ul>{nameList}</ul>
}
위와 같이 자바스크립트 배열 객체의 내장 함수인 map 함수를 사용하여 반복되는 컴포넌트를 렌더링할 수 있습니다. map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 생성한다.
arr.map( callback, [thisArg] )
• callback: 새로운 배열의 요소를 생성하는 함수로 파라미터는 다음 세 가지입니다.
- currentValue: 현재 처리하고 있는 요소
- index: 현재 처리하고 있는 요소의 index 값
- array: 현재 처리하고 있는 원본 배열
• thisArg(선택 항목): callback 함수 내부에서 사용할 this 레퍼런스
이제 위에 작성한 컴포넌트의 결과를 알아보자
컴포넌트를 임포트하여 써 보면 아래와 같은 결과가 나온다.
원하는 대로 렌더링이 되었지만 완벽하지는 않습니다. 크롬 개발자 도구의 콘솔을 열어 보자.
"key"prop이 없다는 경고 메시지를 표시한다. 이제 key를 알아 보자.
리액트에서 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용한다. 유동적인 데이터를 다룰 때는 key가 없다면 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지한다. 하지만 key가 있다면 이 값을 이용하여 어떤 변화가 일어났는지 더욱 빠르게 알아낼 수 있다.
key 값을 성정할 때는 map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯 설정하면 된다. key값은 언제나 유일해야한다. 따라서 데이터가 가진 고윳값을 key값으로 설정해야 한다.
무슨 소리인지 아래의 코드를 보자. 게시판의 게시물을 렌더링한다면 아래처럼 게시물 번호를 key값으로 설정해야 한다.
const articleList = articles.map(article =>(
<Article
title={article.title}
writer={article.writer}
key={article.id}
/>
그럼 map함수에서 예를 들었던 컴포넌트는 고유 번호가 없는데요? 이때는 map 함수에 전달되는 콜백 함수의 인수인 index 값을 사용하면 된다.
const IterationSample = ()=>{
const names = ['눈사람', '얼음', '눈', '바람'];
const nameList = names.map(( name, index )=><li key={index}>{name}</li>);
return <ul>{nameList}</ul>
}
자 무엇이 바뀌었는지 확인 후 개발자 도구를 보면 더 이상 경고 메시지를 표지하지 않는다. 하지만 고유한 값이 없을 때만 index 값을 사용해야 한다. index를 key로 사용하면 배열이 변경될 때 효율적으로 리렌더링하지 못한다고 한다...!