arr.map(callback, [thisArg])
import React from "react";
const IterationSample = () => {
const names = ["눈사람", "얼음", "눈", "바람"];
const nameList = names.map((name) => <li>{name}</li>);
return <ul>{nameList}</ul>;
};
export default IterationSample;
위 코드의 실행결과 콘솔에 key가 없다는 경고 메시지 출력된다.
key
는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용한다.
key가 없을 때는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지하지만 key가 있다면 어떤 변화가 일어났는지 더욱 빠르게 알아낼 수 있다.
key값은 언제나 유일해야 한다.
const articleList = articles.map(article => (
<Article
title={article.title}
writer={article.writer}
key={article.id}
/>
);
만약 고유한 값이 없다면 index 값을 사용한다. 하지만 index를 key로 사용하면 배열이 변경될 때 효율적으로 리렌더링하지 못한다.
import React, { useState } from "react";
const IterationSample = () => {
const [names, setNames] = useState([
// 객체 형태로 이루어진 데이터 배열
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" },
]);
const [inputText, setInputText] = useState(""); //input의 상태
const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 고유 id
const nameList = names.map((name) => <li key={name.id}>{name.text}</li>);
return <ul>{nameList}</ul>;
};
export default IterationSample;
import React, { useState } from "react";
const IterationSample = () => {
const [names, setNames] = useState([
// 객체 형태로 이루어진 데이터 배열
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" },
]);
const [inputText, setInputText] = useState(""); //input의 상태
const [nextId, setNextId] = useState(5); // 새로운 항목을 추가할 때 사용할 고유 id
const onChange = (e) => setInputText(e.target.value);
const onClick = () => {
const nextNames = names.concat({
id: nextId,
text: inputText,
});
setNextId(nextId + 1);
setNames(nextNames);
setInputText("");
};
const nameList = names.map((name) => <li key={name.id}>{name.text}</li>);
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
};
export default IterationSample;
버튼을 클릭할 때 배열의 내장 함수 concat
을 사용하여 새로운 항목을 추가한 배열을 만들고 setNames를 통해 상태를 업데이트해준다.
push vs concat
push
: 기존 배열 자체를 변경
concat
: 새로운 배열 생성리액트에서 상태를 업데이트할 때는 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야 한다. ➡️ 불변성 유지
각 항목을 더블클릭했을 때(onDoubleClick
) 해당 항목이 화면에서 사라지는 기능 구현
위에서의 concat과 마찬가지로 불변성을 유지하면서 업데이트해 주어야 한다. 불변성을 유지하면서 배열의 특정 항목을 지울 때 filter
함수 사용
onRemove
함수를 생성해 각 li 요소에 이벤트를 등록한다.
const onRemove = (id) => {
const nextNames = names.filter((name) => name.id !== id);
setNames(nextNames);
};
const nameList = names.map((name) => (
<li key={name.id} onDoubleClick={() => onRemove(name.id)}>
{name.text}
</li>
));
- 컴포넌트 배열을 렌더링할 때는 key값 설정에 항상 주의해야 한다.
- 상태 안에서 배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아닌
concat
,filter
등의 배열 내장 함수를 사용해 새로운 배열을 만든 후 새로운 상태로 설정한다.