[Westagram] Mission 5) map 함수 적용시 key props를 부여하는 이유

Lemon·2022년 5월 16일
0

React

목록 보기
6/21
post-thumbnail

참고


map() 간단하게 살펴보기

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를 넣어야할까??

리액트에서 배열을 렌더링할때는 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> );

위 배열에 bc사이에 z를 삽입한다면, 리렌더링 될 때 기존의 cz로 바뀌고, dc로 바뀌고, 맨 마지막에 d가 새로 삽입된다. 간단하게 말하면 인덱스가 한칸씩 뒤로 밀린다. 무려 3개의 요소가 재 배치 되는것이다.

근데 만약 배열에 각 요소에 고유한 id값이 있고

const array = [ 
	{ id: 0, text: 'a'},
	{ id: 1, text: 'b'},
	{ id: 2, text: 'c'},
	{ id: 3, text: 'd'}
]

item.idkey값으로 갖는 함수가 있다면

array.map( item => <div key={ item.id }> {item} </div> );

배열이 업데이트 될 때 수정되지 않는 기존의 값은 그대로 두고 원하는 곳에 추가하거나 삭제한다.


key로 컴포넌트 추출하기

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를 부여하는 이유는 배열이 업데이트 될 때 효율적으로 렌더링 될 수 있기 때문이다.

profile
프론트엔드 개발자 가보자고~!!

4개의 댓글

comment-user-thumbnail
2022년 5월 17일

map 과 forEach 차이도 알아보세요 도움 될꺼에요 ㅎㅎ

1개의 답글
comment-user-thumbnail
2022년 5월 19일

정리천재 주영님 화이팅!!

1개의 답글