map() 함수
map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 반환합니다.
arr.map(callback,[thisArg])
- callback: 새로운 배열의 요소를 생성하는 함수로 파라미터는 다음 세가지
- currentValue: 현재 처리하고 있는 요소
- index: 현재 처리하고 있는 요소의 index 값
- array: 현재 처리하고 있는 원본 배열
- thisArg(선택항목): callback 함수 내부에서 사용할 this 레퍼런스
데이터 배열을 컴포넌트 배열로 변환하기
const IterationSample = () => {
const names = ['눈사람','얼음','눈','바람'];
const nameList = names.map(name=><li>{name}</li>);
return <ul>{nameList}</ul>
}
이런식으로 작성하면 원하는대로는 잘 동작하겠지만 개발자 도구를 열어 확인해보면
🚨 Warning: Each child in a list should have a unique "key" prop
이런 오류를 뱉는 것을 확인할 수 있습니다!
key
리액트에서 key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용합니다.
key가 없다면 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지하게 됩니다.
하지만 key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빨리 알아낼 수 있습니다!
key 설정
key를 설정할 때는 map 함수의 인자로 전달되는 함수 내부에서 컴포넌트 props를 설정하듯이 설정하면 됩니다.
key 값은 언제나 유일해야 합니다!
데이터가 가진 고윳값을 key 값으로 설정해야 합니다.
const IterationSample = () => {
const names = ['눈사람','얼음','눈','바람'];
const nameList = names.map((name,index)=><li key={index}>{name}</li>);
return <ul>{nameList}</ul>
}
고유한 값이 없을때만 index를 사용하는 것이 좋습니다.
data의 기본적으로 id가 있다면 이를 이용하는 방법도 좋습니다!
응용
import { useState } from 'react'
const IterationSample = () => {
const names = 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,index)=><li key={name.id}>{name.text}</li>);
return (<>
<input value={inputText} onChange={onChange} />
<button>추가</button>
<ul>{nameList}</ul>
</>);
}
export default IterationSample;
위는 기존 data의 id를 이용하며 새롭게 추가하는 데이터의 고윳값 관리도 가능합니다!
concat을 사용한 이유는, push 함수는 기존 배열 자체를 변경해 주는 반면, concat은 새로운 배열을 만들어줍니다.
filter를 활용한 데이터 제거 만들기
(...)
const onRemove = id => {
const nextNames = names.filter(name => name.id !== id);
setNames(nextNames);
}
const nameList = names.map((name,index)=><li key={name.id} onDoubleClick={()=>onRemove(name.id)}>{name.text}</li>);
(...)
위와 같이 filter를 사용하면 해당 id에 해당하지 않는 값들만 반환할 수 있게 되고, 데이터가 제거된 값이 반환되게 됩니다!
[JS] forEach, map, reduce, every, filter 사용법 (opens in a new tab)
다양한 함수 형태가 있으니 참조해두는 것이 좋을 것 같습니다~~