map 메서드는, 요소에 콜백 함수를 실행한 결과를 모아 완전히 새로운 배열을 return합니다.
이처럼 새로운 배열을 반환하는 map 메서드의 특성을 React의 JSX에서 활용할 수 있습니다. map 메서드를 이용하여 배열 형태의 데이터로 반복되는 UI를 효율적으로 구성할 수 있습니다.
위와 같이 같은 구조의 댓글이 여러 개 달린 UI를 생각해 봅시다.
//Comment.js
import React from 'react';
const Comment = () => {
return (
<ul>
<li className="feed__comment">
<span className="user-ID">JMJ</span>
<span className="comment__text">나도 가고 싶어...</span>
</li>
<li className="feed__comment">
<span className="user-ID">JMJ</span>
<span className="comment__text">빨리 가고 싶어...</span>
</li>
<li className="feed__comment">
<span className="user-ID">JMJ</span>
<span className="comment__text">퇴근 하고 싶다...</span>
</li>
</ul>
);
};
export default Comment;
위와 같은 형태가 될 것입니다. 보시다시피, 댓글 text만 다르고 같은 형태의 태그가 반복되고 있습니다.
이런 경우에 매번 다르게 들어가는 데이터(text)를 배열로 만들고, JSX 안에서 해당 배열에 map 메서드를 활용하면, 간단히 UI를 구성할 수 있습니다.
//Comment.js
import React from 'react';
const Comment = () => {
return (
<ul>
{COMMENT_LIST.map(comment => (
<li className="feed__comment">
<span className="user-ID">JMJ</span>
<span className="comment__text">{comment}</span>
</li>
))}
</ul>
);
};
COMMENT_LIST = [ "나도 가고 싶어...", "빨리 가고 싶어...", "퇴근 하고 싶다..."];
export default Comment;
span 안에 text로 들어가는 데이터를 COMMENT_LIST라는 배열에 담고, 컴포넌트가 return하는 JSX 내부에서 해당 배열에 map 메서드를 활용해 댓글의 전체 태그를 return하도록 구성했습니다.
그런데 이대로 실행하면 화면은 잘 그려지지만, 콘솔 패널에 아래와 같은 경고창이 뜹니다.
‘배열의 각 요소마다 고유의 key prop을 가지고 있어야 한다’ 라고 경고하고 있습니다.
React는 배열을 렌더링할 때, 요소가 가진 특정 값을 통해 변화를 인식하고, 업데이트를 최적화합니다. 이때 요소에 고유성을 부여하는 특정 값이 바로 key prop입니다.
key를 선택하는 가장 좋은 방법은 해당 항목을 고유하게 식별할 수 있는 값을 사용하는 것입니다. 대부분의 경우 데이터의 id를 key로 사용합니다.
이에 따라 각 댓글 요소에 key prop을 부여하여 다시 데이터를 만들어 봅시다.
const COMMENT_LIST = [
{ id: 1, text: '나도 가고 싶어...' },
{ id: 2, text: '빨리 가고 싶어...' },
{ id: 3, text: '퇴근 하고 싶어...' },
];
위 데이터를 이용해 댓글 컴포넌트를 다시 구성해보면 아래와 같습니다.
//Comment.js
import React from 'react';
const Comment = () => {
return (
<ul>
{COMMENT_LIST.map(comment => (
<li className="feed__comment">
<span className="user-ID">JMJ</span>
<span key={comment.id} className="comment__text">{comment.text}</span>
</li>
))}
</ul>
);
};
const COMMENT_LIST = [
{ id: 1, text: '나도 가고 싶어...' },
{ id: 2, text: '빨리 가고 싶어...' },
{ id: 3, text: '퇴근 하고 싶어...' },
];
export default Comment;
데이터에 고유한 값이나 id가 없는 경우, 최후의 수단으로 배열 요소의 index를 key로 활용할 수 있으나, 요소의 순서가 바뀔 수 있는 경우 key에 index를 사용하는 것은 권장하지 않습니다. 이로 인해 성능이 저하되거나 컴포넌트의 state와 관련된 문제가 발생할 수 있기 때문입니다.
만약 데이터의 각 요소가 고유하다는 확신이 있다면, 그대로 요소 자체를 key prop으로 사용하면 됩니다. 이 데이터의 경우 이미 유니크한 값을 가지고 있기 때문에, 해당 값을 key prop으로 바로 부여할 수도 있습니다.