참고
- 리스트와 Key - React 👀 리액트 공식문서
- 11. 배열 렌더링하기 👀 벨로퍼트 배열 렌더링하기
const numbers = [1, 2, 3, 4];
const doubled = numbers.map((numb) => num * 2);
console.log(doubled) // [2, 4, 6, 8]
배열안에 있는 각 원소를 변환해 새로운 배열을 만들어준다.
리액트로 동적인 배열을 렌더링 할 때는 map() 함수를 사용한다.
numbers
배열을 받아서 순서 없는 엘리먼트 리스트를 출력하는 컴포넌트를 만들어보자.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
리스트의 각 항목에 key
를 넣어야 한다는 경고가 표시된다.
리액트에서 배열을 렌더링할때는 key
라는 props를 설정해야한다.
key
는 어떤 항목을 변경, 추가, 삭제할지 식별하는 것을 돕는다.
key
값은 각 원소들마다의 고유한 값으로 설정해야한다.
원소들의 고유성을 위해 배열 내부의 원소들에게 지정해야한다.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
key
선택의 가장 좋은 방법은 고유한 문자열을 사용하는 것이다.
대부분의 경우 데이터의 ID를 key
로 사용한다.
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
만약 배열을 렌더링 할 때 key
를 설정하지 않았다면 배열의 index값을 key
로 사용하게 되고, 아까봤던 경고메세지가 뜬다.
배열의 고유 원소에 key가 있어야 배열이 업데이트 될 때 효율적으로 렌더링 될 수 있기 때문이다.
const array = ['a', 'b', 'c', 'd']
위의 배열을 아래와 같이 렌더링한다고 가정해보자.
array.map( item => <div>{item}</div> );
위 배열에 b
와 c
사이에 z
를 삽입한다면, 리렌더링 될 때 기존의 c
가 z
로 바뀌고, d
가 c
로 바뀌고, 맨 마지막에 d
가 새로 삽입된다. 간단하게 말하면 인덱스가 한칸씩 뒤로 밀린다. 무려 3개의 요소가 재 배치 되는것이다.
근데 만약 배열에 각 요소에 고유한 id
값이 있고
const array = [
{ id: 0, text: 'a'},
{ id: 1, text: 'b'},
{ id: 2, text: 'c'},
{ id: 3, text: 'd'}
]
item.id
를 key
값으로 갖는 함수가 있다면
array.map( item => <div key={ item.id }> {item} </div> );
배열이 업데이트 될 때 수정되지 않는 기존의 값은 그대로 두고 원하는 곳에 추가하거나 삭제한다.
key는 주변 배열의 컨텐트에서만 의미가 있다.
예를들어 ListItem
컴포넌트를 추출한 경우 ListItem
안에 있는 <li>
엘리먼트가 아니라 📌map()을 사용한 배열의 <ListItem />
엘리먼트가 key를 가져야한다.
function ListItem(props) {
// 여기에는 key를 지정할 필요가 없다.
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// 배열 안에 key를 지정해야 한다.
<ListItem key={number.toString()} value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
Key는 형제 사이에서만 고유한 값이어야 한다.
전체 범위에서 고유할 필요는 없다.
map()
과 Key
westagram 프로젝트를 진행하면서 댓글 구현할 떄 배열에 map을 사용했다.
다른 코드들은 전부 제외하고 map과 key를 사용한 부분만 남겨보았다.
위에서 봤던 것처럼 comment 에 고유한 id값을 주고
map() 함수를 이용해 comment박스인 ul안에 li들을 map으로 state 배열 길이만큼 추가하면서 Comment의 key값으로 id를 줬다.
map 함수 적용시 key props를 부여하는 이유는 배열이 업데이트 될 때 효율적으로 렌더링 될 수 있기 때문이다.
map 과 forEach 차이도 알아보세요 도움 될꺼에요 ㅎㅎ