배열 객체의 내장 함수인 map을 사용해 반복되는 컴포넌트를 렌더링할 수 있다.
// 새로운 배열 반환
arr.map(callback, [thisArg])
arr.map((currentValue, index, array) => { ... })
callback
- currentValue : 현재 처리 중인 요소
- index : 현재 처리 중인 요소의 인덱스
- array : 현재 처리 중인 원본 배열
[thisArg]
callback 함수 내부에서 사용할 this 레퍼런스
🐣 예시
var numbers = [1,2,3,4,5]
const result = numbers.map(num=> {
return num * num
})
console.log(result) // [1,4,9,16,25]
import React from "react";
const IterationSample = () =>{
const names = ['a','b','c','d']
const nameList = names.map(name => <li>{name}</li>)
return <ul>{nameList}</ul>
}
export default IterationSample
위와 같은 배열의 b와 c 사이에 z를 삽입하게 되면, 리렌더링을 하는 경우 b와 c 사이에 새로운 div 태그를 삽입하는 것이 아니라 기존의 c → z, d → c로 바뀐 후 맨 마지막에 d가 새롭게 삽입된다. 즉, 새롭게 추가된 부분 이하 배열 요소에 전부 영향을 준다.
이후 [a, b, z, c, d] 에서 a를 제거하면, 기존의 a → b, b → c, z → c, c → d로 바뀌며 맨 마지막에 있는 d는 제거된다. 배열 요소의 삭제도 변경된 배열 요소 이하 배열 요소에 모두 영향을 끼친다.
즉 key가 없는 경우, virtual DOM을 비교하는 과정에서 변경이 필요하지 않은 배열의 요소까지 변경이 일어나게 되므로 비효율적이다. 이런 부분을 개선하기 위해서 key를 사용한다.
import React from "react";
const IterationSample = () =>{
const names = ['a','b','c','d']
const nameList = names.map((name, index) => <li key={index}>{name}</li>)
return <ul>{nameList}</ul>
}
export default IterationSample
❗고유한 값이 없을 때만 index 값을 key로 사용해야 한다. index를 key로 사용하면 배열이 변경될 때 효율적으로 리렌더링하지 못한다.
IterationSample.js
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('')
const [nextId, setNextId] = useState(5) // 새 항목 추가 시 사용할 id
const onChange = (e) => {
setInputText(e.target.value)
}
// 데이터 추가 기능
const onClick = (e) => {
const nextNames = [...names, {id:nextId, text:inputText}]
setNames(nextNames)
setNextId(nextId + 1)
setInputText('')
}
const onKeyUp = (e) =>{
if(e.key === 'Enter'){
onClick()
}
}
// 각 항목 더블클릭 시 데이터 제거 기능
const onRemove = (id) => {
const nextNames = names.filter(name =>
id !== name.id
)
setNames(nextNames)
}
const nameList = names.map( name => {
return <li
key={name.id}
onDoubleClick={() => onRemove(name.id)}>{name.text}</li>
})
// onDoubleClick={onRemove(name.id)} 이렇게 쓰면 안됨
// 이벤트에서 실행할 자바스크립트 코드는 함수 형태로 전달해야 한다.
return (
<>
<input value={inputText} onChange={onChange} onKeyUp={onKeyUp} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</>
)
}
export default IterationSample