
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.
const arr = [1, 2, 3, 4, 5]
이런 배열이 있다.
배열 안에 있는 모든 요소를 제곱하여 새로운 배열을 만들고 싶다면 어떻게 해야 할까?
바로 map() 메서드를 사용하면 된다.
const arr = [1, 2, 3, 4, 5];
const mapArr = arr.map(num => num * num);
console.log(arr);
// > Array [1, 2, 3, 4, 5]
console.log(mapArr);
// > Array [1, 4, 9, 16, 25]
map() 메서드 안에 들어가는 내용은 callback함수이다.
배열 arr에 있는 요소(num)들에 함수를 실행하고 나온 값(num * num)을 저장하여 새로운 배열(mapArr)로 만든다.
map() 활용하기
배열의 요소들을 화면에 그리도록 map() 을 활용해 볼 것이다.
App.js
import "./App.css";
import Test01 from "./07/Test01";
function App() {
return (
<div className='App'>
<Test01 />
</div>
);
}
export default App;
Test01 함수 컴포넌트
import React from "react";
export default function Test01() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
// map() 함수
const todos = todoList.map((todo) => <div>{todo.taskName}</div>);
return (
<>
<label>TO DO</label>
{todos}
</>
);
}
Test01 클래스 컴포넌트
import React, { Component } from "react";
class Test01 extends Component {
render() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
// map() 함수
const todos = todoList.map((todo) => <div>{todo.taskName}</div>);
return (
<>
<label>TO DO</label>
{todos}
</>
);
}
}
export default Test01;
객체를 요소로 가진 todoList 라는 배열을 만들었다.
taskName 을 화면에 그리고 싶어, map() 함수를 사용했다.
const todos = todoList.map((todo) =>
todo의 taskName만 가져와 todos 라는 이름을 가진 컴포넌트가 map() 함수를 돌면서 출력될 것이다.
만약 map()이 없었더라면?!
배열에서 일일이 꺼내기
Test02 함수 컴포넌트
import React from "react";
export default function Test02() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
<label>TO DO</label>
<div>{todoList[0].taskName}</div>
<div>{todoList[1].taskName}</div>
</>
);
}
Test02 클래스 컴포넌트
import React, { Component } from "react";
class Test02 extends Component {
render() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
<label>TO DO</label>
<div>{todoList[0].taskName}</div>
<div>{todoList[1].taskName}</div>
</>
);
}
}
export default Test02;
이렇게 일일이 todoList 배열의 요소들을 선택하여 꺼내주어야 한다.
위처럼 배열의 요소가 적다면 일일이 꺼내는 게 어려운 일은 아니겠지만,
만약 배열의 요소의 개수가 사용자에 의해 변한다거나 점점 많아질수록 일일이 꺼내기 어려워지며, 코드도 불필요하게 길어지게 될 것이다.
map()과 key
Warning: Each child in a list should have a unique "key" prop
map() 함수를 사용하면 콘솔창에 위와 같은 에러가 뜰 것이다.
대충 해석해보니 리스트에 유니크한 키 값이 없다는 것 같다.
React는 key Prop을 사용하여 컴포넌트와 DOM 요소 간의 관계를 생성한다.
이렇게 생성된 관계를 이용하여 컴포넌트 리렌더링 여부를 결정하는데,
불필요한 리렌더링을 방지하기 위해서 자식 컴포넌트마다 독립적인 key 값을 주어야 한다.
key 값 주기
Test01 함수 컴포넌트
import React from "react";
export default function Test01() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
{todoList.map((todo, i) => (
<div key={`tl-${i}`}>{todo.taskName}</div>
))}
</>
);
}
Test01 클래스 컴포넌트
import React, { Component } from "react";
class Test01 extends Component {
render() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
{todoList.map((todo, i) => (
<div key={`tl-${i}`}>{todo.taskName}</div>
))}
</>
);
}
}
export default Test01;
map() 을 사용하여 각 컴포넌트에 배열의 index로 고유한 key 값 을 주었다.
그러나, 배열의 index 를 key 값 으로 주는 것은 지양해야 한다.
배열의 요소들의 순서가 바뀌는 경우에는 배열 요소의 index 도 바뀌고, 컴포넌트마다 고유한 key 값 도 같이 바뀐다.
이러면 리액트는 리렌더링 해야하는 컴포넌트를 헷갈려 다른 컴포넌트를 리렌더링할 수도 있다.
key 값 은 전역적으로 고유할 필요는 없고, 형제 사이에서 고유해야 한다.
Test01 함수 컴포넌트
import React from "react";
export default function Test01() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
{todoList.map((todo) => (
<div key={todo.taskName}>{todo.taskName}</div>
))}
</>
);
}
Test01 클래스 컴포넌트
import React, { Component } from "react";
class Test01 extends Component {
render() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
{todoList.map((todo) => (
<div key={todo.taskName}>{todo.taskName}</div>
))}
</>
);
}
}
export default Test01;
그래서 한 번 taskName 을 key 값 으로 주었다.
콘솔에 있던 오류 창이 사라졌다!
filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
위에서 만들었던 todoList 배열이다.
filter() 메서드를 활용하여 finished 가 false 인 것만 화면에 그리도록 해보려고 한다.
Test01 함수 컴포넌트
import React from "react";
export default function Test01() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
{todoList
.filter((todo) => todo.finished === false)
.map((todo, i) => (
<div key={todo.taskName}>{todo.taskName}</div>
))}
</>
);
}
Test01 클래스 컴포넌트
import React, { Component } from "react";
class Test01 extends Component {
render() {
const todoList = [
{ taskName: "방 청소", finished: false },
{ taskName: "화장실 청소", finished: true },
];
return (
<>
{todoList
.filter((todo) => todo.finished === false)
.map((todo, i) => (
<div key={todo.taskName}>{todo.taskName}</div>
))}
</>
);
}
}
export default Test01;