목표
- Array 메서드인 Map, Filter에 대해 알아본다.
- Key와 리렌더링의 관계를 알아본다.
const todo = [
{ id: 1, value: "go to cafe" },
{ id: 2, value: "studying" },
{ id: 3, value: "go to restaurant" },
{ id: 4, value: "running" }
];
const App = () => {
const [items, setItems] = React.useState(todo);
return (
<>
{items.map((item) => (
<div className="wrapper">
<span>{item.value}</span>
<button className="done-button">Done</button>
</div>
))}
</>
);
};
Array.prototype.map()
- map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환하는 역할을 한다.
- arr.map(callback(currentValue[, index[, array]])[, thisArg])
- 콜백 함수의 매개 변수로 currentValue(처리할 현재 요소), index(처리할 현재 요소의 인덱스), array(map을 호출한 배열), thisArg(callback을 실행할 때 this로 사용되는 값)가 올 수 있다.
- 그 중에서도 currnetValue는 필수 인자이다. 나머지 index, array, thisArg는 상황에 따라 넣을 수 있는 선택 인자이다.
- 자세한 내용은 Mozila - Array.prototype.map()를 참조하면 된다.
🤔 의문
- 할 일을 할 때마다 Done 버튼을 눌러 할 일을 지우려면 어떻게 해야 할까?
여러 방법이 있지만 Array의 filter 메서드를 사용하면 쉽게 지울 수 있다.
// 생략
const onClick = (todo) => {
setItems((items) => items.filter((item) => item !== todo));
};
return (
<>
{items.map((item) => (
<div className="wrapper">
<span>{item.value}</span>
<button className="done-button" onClick={() => onClick(item)}>
Done
</button>
</div>
))}
</>
);
Array.prototype.filter()
- filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.
- arr.filter(callback(element[, index[, array]])[, thisArg])
- 위에서 언급했던 map함수와 매개변수로 들어갈 수 있는 인자는 같다.
- 콜백 함수의 매개 변수로 element(처리할 현재 요소), index(처리할 현재 요소의 인덱스), array(map을 호출한 배열), thisArg(callback을 실행할 때 this로 사용되는 값)가 올 수 있다.
- 그 중에서도 element 필수적인 인자이며, 나머지 index, array, thisArg는 상황에 따라 넣을 수 있는 선택적인 인자이다.
- 자세한 내용은 Mozila - Array.prototype.filter()를 참조하면 된다.
위에서 작성한 코드가 문제 없이 돌아가는 건 맞지만 콘솔에는 에러가 계속 찍힌다.
const todo = [
[
{ id: 1, value: "go to cafe" },
{ id: 2, value: "studying" },
{ id: 3, value: "go to restaurant" },
{ id: 4, value: "running" }
],
[
{ id: 2, value: "studying" },
{ id: 3, value: "go to restaurant" },
{ id: 4, value: "running" },
{ id: 1, value: "go to cafe" }
],
[
{ id: 3, value: "go to restaurant" },
{ id: 4, value: "running" },
{ id: 1, value: "go to cafe" },
{ id: 2, value: "studying" }
],
[
{ id: 4, value: "running" },
{ id: 1, value: "go to cafe" },
{ id: 2, value: "studying" },
{ id: 3, value: "go to restaurant" }
]
];
const [items, setItems] = React.useState(todo[0]);
React.useEffect(() => {
const interval = setInterval(() => {
const random = Math.floor(Math.random() * 4);
setItems(todo[random]);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
🤔 의문
- 그렇다면 어떻게 해야 완전히 컴포넌트를 재사용할 수 있을까?
return (
<>
{items.map((item) => (
<div className="wrapper" key={item.id}>
<button className="todo" onClick={() => onClick(item)}>
{item.value}
</button>
</div>
))}
</>
);
🤔 의문
- 그렇다면 위에서 배웠던 map() 함수의 index 파라미터를 사용해도 똑같이 동작할까?
return (
<>
{items.map((item, index) => (
<div className="wrapper" key={index}>
<button className="todo" onClick={() => onClick(item)}>
{item.value}
</button>
</div>
))}
</>
);