map()함수는 자바스크립트의 배열 메서드로, 배열의 각 요소에 대해 주어진 콜백 함수를 호출하고 그 결과를 새로운 배열로 반환하는 도구이다. 특히 리액트에서 map()은 배열 데이터를 화면에 렌더링할 때 자주 사용된다. map() 함수의 기본 사용법부터 리액트에서의 실전 활용 사례까지 살펴보자.
추가로 Callback 함수는 다른 함수에 인수로 전달되어 나중에 실행되는 함수를 말한다. 자바스크립트는 함수도 값으로 취급할 수 있기 때문에, 함수를 인수로 전달하거나 반환값으로 사용할 수 있다. 콜백 함수는 주로 비동기 작업(ex. 이벤트 처리, 데이터 요청)이나 동작을 커스터마이즈할 때 많이 사용된다.
array.map((currentValue, index, array) => {
// 새 배열에 대한 반환값
});
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]
위 코드에서 numbers 배열의 각 요소에 2를 곱한 값을 새로운 배열로 반환한다.
리액트에서는 데이터를 기반으로 컴포넌트를 동적으로 생성할 때 map()이 필수적으로 사용된다. 주로 배열 데이터를 JSX로 변환하여 렌더링하는 경우이다.
import React from "react";
const fruits = ["Apple", "Banana", "Cherry"];
function FruitList() {
return (
<ul>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
);
}
export default FruitList;
{items.map((item) => (
<div key={item.id}>{item.name}</div>
))}
고유한 id 값이 있는 경우 이를 key로 사용하는 것이 권장된다.
배열의 index를 key로 사용하는 것은 일반적으로 피하는 것이 좋지만, 고유 식별자가 없을 때 임시로 사용할 수 있다.
배열에서 특정 조건을 만족하는 항목만 렌더링하려면 filter()와 map()을 함께 사용할 수 있다.
const tasks = [
{ id: 1, name: "Task 1", completed: true },
{ id: 2, name: "Task 2", completed: false },
{ id: 3, name: "Task 3", completed: true },
];
function TaskList() {
return (
<ul>
{tasks
.filter(task => task.completed)
.map(task => (
<li key={task.id}>{task.name}</li>
))}
</ul>
);
}
배열 데이터를 기반으로 여러 개의 하위 컴포넌트를 생성할 수도 있다.
function User({ name, age }) {
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
</div>
);
}
const users = [
{ id: 1, name: "Alice", age: 25 },
{ id: 2, name: "Bob", age: 30 },
];
function UserList() {
return (
<div>
{users.map(user => (
<User key={user.id} name={user.name} age={user.age} />
))}
</div>
);
}
잘못된 예
{items.map(item => <div>{item.name}</div>)}
→ key가 없어 리액트 경고가 발생한다.
올바른 예
{items.map(item => <div key={item.id}>{item.name}</div>)}
잘못된 예
items.map(item => {
<div key={item.id}>{item.name}</div>; // 반환값 없음
});
{}를 사용한 경우, 자바스크립트는 이를 함수 본문(body)으로 해석한다.return 키워드를 사용해야 한다.return이 없으므로 undefined가 반환된다.올바른 예
items.map(item => (
<div key={item.id}>{item.name}</div>
));
()를 사용한 경우, 이는 암시적 반환(implicit return)을 의미한다.item => (...) 형태에서는 괄호 안의 값이 자동으로 반환됩니다.<div key={item.id}>{item.name}</div>가 반환되고, map() 함수가 새로운 배열을 생성할 수 있디.배열이 중첩된 경우 중첩된 map() 사용 시 적절한 key를 설정해야 한다.
const categories = [
{ id: 1, name: "Fruits", items: ["Apple", "Banana"] },
{ id: 2, name: "Vegetables", items: ["Carrot", "Lettuce"] },
];
function CategoryList() {
return (
<div>
{categories.map(category => (
<div key={category.id}>
<h2>{category.name}</h2>
<ul>
{category.items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
))}
</div>
);
}
forEach()
배열 요소를 반복 실행하지만 반환값이 없다.
array.forEach(item => console.log(item));
reduce()
배열을 순회하며 누적된 결과를 반환한다.
const sum = numbers.reduce((acc, cur) => acc + cur, 0);
map()함수는 배열 데이터를 처리하고 UI에 반영하는 데 있어 필수적인 도구다. 리액트에서는 특히 컴포넌트의 동적 렌더링에 없어서는 안 될 중요한 메서드이다. 올바른 key 설정과 조건부 렌더링 패턴 등을 잘 활용하면 효율적이고 유지보수 가능한 코드를 작성할 수 있다.
map 함수에 대해 잘 배워 갑니다!
"JSX를 반환하지 않음" 에 대해 완전 공감입니다 😭