블로그 포스트가 두 개밖에 없다면 아래 코드로 충분할 것이다. 이렇게 직접 모든 데이터를 코드에 작성하는 것을 하드코딩(hard coding)
이라고 부른다.
const posts = [
{ id: 1, title: "Apple", content: "이것들이 무너져야" },
{ id: 2, title: "Tesla", content: "하락장이 끝난다" },
];
function Blog() {
return (
<div>
<div>
<h3>{posts[0].title}</h3>
<p>{posts[0].content}</p>
</div>
<div>
<h3>{posts[1].title}</h3>
<p>{posts[1].content}</p>
</div>
</div>
);
}
하지만 블로그 포스트가 100개인 경우엔 블로그 포스팅이 늘어날 때마다 매일 코드를 변경해야만 한다. 데이터가 변경될 때마다, 알아서 렌더링할 수는 없을까? React에서는 이런 문제를 해결하기 위해서 배열 메서드 map
을 활용한다.
const posts = [
{ id : 1, title : "Apple", content: "이것들이 무너져야" },
{ id : 2, title : "Tesla", content: "하락장이 끝난다" },
{ id : 3, title : 'Meta', content : '얘는 이미 가치투자 할만하다.' },
// ...
{ id : 100, title : 'Nvidia', content : '넌 좀 더 맞아야 한다' },
];
function Blog() {
return (
<div>
<div>
<h3>{posts[0].title}</h3>
<p>{posts[0].content}</p>
</div>
<div>
<h3>{posts[1].title}</h3>
<p>{posts[1].content}</p>
</div>
{// ...}
<div>
<h3>{posts[99].title}</h3>
<p>{posts[99].content}</p>
</div>
{// ... 98 * 4 more lines !!}
</div>
);
}
이렇게 하드코딩을 하면 답이 없다.
function Blog() {
const postToElement = (post) => (
<div>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
const blogs = posts.map(postToElement);
return <div className="post-wrapper">{blogs}</div>;
}
※ return 문 안에서 map 메서드를 사용할 수는 없을까요?
사용할 수 있다. JSX를 사용하면 중괄호 안에 모든 표현식을 포함할 수 있기 때문에 map 메서드의 결과를 return문 안에 인라인으로 처리할 수 있다. 코드 가독성을 위해 변수로 추출할지 아니면 인라인에 넣을지는 개발자가 판단해야 할 몫이다.
React에서 map 메서드 사용 시, key 속성을 넣지 않으면 아래와 같이 리스트의 각 항목에 key를 넣어야 한다는 경고가 표시된니다. key 속성의 위치는 map 메서드 내부에 있는 엘리먼트 즉, 첫 엘리먼트에 넣어야 한다.
※ key 속성값이 반드시 id가 되어야 하나요? id가 존재하지 않으면 어떻게 해야 하나요?
key 속성값은 가능하면 데이터에서 제공하는 id를 할당해야 한다. key 속성값
은 id와 마찬가지로 변하지 않고, 예상 가능하며, 유일해야 하기 때문이다. 정 고유한 id가 없는 경우에만 배열 인덱스를 넣어서 해결할 수 있다. 배열 인덱스는 최후의 수단(as a last resort)으로만 사용한다.
function Blog() {
// postToElement라는 함수로 나누지 않고 아래와 같이 써도 무방합니다.
const blogs = posts.map((post) => (
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
));
return <div className="post-wrapper">{blogs}</div>;
}