React에선 기존에 한땀한땀 작성해야했던 배열을 map()함수를 이용해 element list로 반복실행할 수 있다.
예를 들어 div안에 feed의 데이터가 담긴 배열(this.state.feeds)에서 배열 값이 하나씩 나타나도록 map()함수를 이용할 때, 아래의 코드를 작성했다.
(실제 코드에서 일부분을 빼내온 터라 보충 설명을 해보자면, 배열 값 feed는 comments, feedContents의 속성을 가지고있다.)
<div className="feeds-wrap">
{this.state.feeds.map(feed => {
return (
<Feeds
comments={feed.comments}
feedsContents={feed}
/>
);
})}
</div>
위 코드를 실행시키면 console에 아래와 같이 list의 모든 child요소는 unique key 속성을 가져야 한다
는 메세지가 출력된다.
그럼 여기서 key는 무엇이고, 왜 필요한 걸까?
Key는 React에서 element list를 만들 때 포함해야 하는 문자열 속성으로, 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다.
Key 값은 list에서 해당 항목을 고유하게 식별할 수 있는 문자열이 가장 좋다.
대부분의 경우 데이터의 ID를 key로 사용한다.
💥 주의 : 배열의 index를 사용하는 건 지양하자
key값을 배열의 index로 지정할 경우, 배열의 순서가 바뀌면 component의 state와 관련된 문제가 발생할 수 있다. component는 key를 기반으로 갱신/재사용되는데 index를 key로 사용하면, 항목의 순서가 바뀌었을 때 key도 변경된다. 따라서 state까지 의도치않게 변경될 수 있다.
명시적으로 key를 지정하지 않을 경우 React는 기본적으로 인덱스를 key로 사용하니, 가급적이면 별도로 key값을 지정하자.
Key값은 위 주의사항을 유념하고 중복되지 않는값을 사용하면 된다.
개인적으로는 밀리초를 포함한 현재시각을 나타내는 Date.now()
를 자주 사용한다.
(다만 적은 양의 mock Data를 구성할 경우 하드코딩으로 1,2,3.. 등으로 주기도 했다.)
아래와 같이 key값이 없는 element로 이루어진 트리에서 새로운 element가 추가될 경우, React는 <ul>
의 모든 자식요소를 다시 변경하므로 비효율적이고 성능이 좋지 않다.
//변경 전 트리
<ul>
<li>딸기</li>
<li>바나나</li>
</ul>
//변경 후 트리: <ul>의 모든 자식요소를 다시 변경한다.
<ul>
<li>복숭아</li>
<li>딸기</li>
<li>바나나</li>
</ul>
key를 이용하면 앞서 말한 비효율성을 해결할 수 있다.
자식요소들이 key를 가지고 있다면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인하므로 트리의 변환이 효율적으로 이루어진다.
//변경 전 트리
<ul>
<li key="2019">딸기</li>
<li key="2020">바나나</li>
</ul>
//변경 후 트리: <key="2018"?> 값만 이동시킨다.
<ul>
<li key="2018">복숭아</li>
<li key="2019">딸기</li>
<li key="2020">바나나</li>
</ul>
React를 공부하며 느낀 점은, 여러개의 component를 렌더링하며 잘 연결시키는 게 정말 중요하다. 그럴 때마다 정말 자주 쓰이는 map함수.
key값도 직접적인 숫자 등을 입력하는 게 아니라 다른 component에서 받아오는 경우가 많다. 사실 console에 경고 메세지만 뜰 뿐 페이지는 잘 돌아가길래 없어도 되나? 싶었는데.. 정확한 연결을 위해선 key값을 꼭 넣어주자 다짐하게된다.
📌 참고 자료
React 공식문서 - 리스트와 Key
React 공식문서 - 재조정 (Reconciliation)