자바스크랩트 배열 객체의 내장 함수인 map함수를 사용하여 반복되는 컴포넌트를 렌더링할 수 있습니다.
map함수는 파라미터로 전달된 함수를 사용하여 배열 내 각 요소를 로직을 수행하고 그 결과를 새로운 배열을 생성합니다.
arr.map(callback, [thisArg])
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
var numbers = [1,2,3,4,5];
var processed = numbers.map(function(num){
return num * num;
});
console.log(processed);
[1,4,9,16,25]
ES6 버전
const numbers = [1,2,3,4,5];
var processed = numbers.map(num=> num * num;);
console.log(processed);
[1,4,9,16,25]
기존 배열로 컴포넌트로 구성된 배열을 생성할 수 있습니다.
/src/components/IterationSample.js
import React from "react";
export default function IterationSample() {
const names = ["눈사람", "얼음", "눈", "바람"];
const nameList = names.map(name => <li>{name}</li>);
return (
<>
<ul>{nameList}</ul>
</>
);
}
리액트에서 key는 컴포넌트 배열을 렌더링 했ㅇ을 때 어떤 원소에 변동이 있었는지 알아내려고 사용합니다.
데이터가 있으면 CRUD 로직을 구현하게 됩니다. key가 없을 때는 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지한다. 하지만 key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빠르게 알아낼 수 있습니다.
key값은 index에 string을 추가하는 방식으로 사용하면 됩니다.
key값이 중복되면 렌더링 과정에서 에러가 발생해요.
import React, { useState } from "react";
export default function IterationSample() {
const [names, setNames] = useState(
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" }
);
const [inputText, setInputTxt] = useState("");
const [nextId, setNextId] = useState(5);
const nameList = names.map(name => <li key={name.id}>{name.text}</li>);
return (
<>
<ul>{nameList}</ul>
</>
);
}
배열 내장함수 concat을 사용하여 새로운 항목을 추가한 새로운 배열을 만들어서 상태를 업데이트합니다.
불변성 유지를 해줘야 컴포넌트 성능을 최적화 할 수 있음. 리액트 상태를 업데이트 메커니즘이 이렇습니다.
import React, { useState } from "react";
export default function IterationSample() {
const [names, setNames] = useState([
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" }
]);
const [inputText, setInputText] = useState("");
const [nextId, setNextId] = useState(5);
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>
</>
);
}
데이터를 제거할때도 불변성을 유지하면서 업데이트해줘야 합니다.
import React, { useState } from "react";
export default function IterationSample() {
const [names, setNames] = useState([
{ id: 1, text: "눈사람" },
{ id: 2, text: "얼음" },
{ id: 3, text: "눈" },
{ id: 4, text: "바람" }
]);
const [inputText, setInputText] = useState("");
const [nextId, setNextId] = useState(5);
const onChange = e => {
setInputText(e.target.value);
};
const onClick = () => {
const nextNames = names.concat({ id: nextId, text: inputText });
setNextId(nextId + 1);
setNames(nextNames);
setInputText("");
};
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>
));
return (
<>
<input value={inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
);
}