2021. 8. 31. 16:27ㆍFrontend/React
리액트에서 Key 값이 필요한 이유
Each child in an array should have a unique “key” prop.
배열에 map() 함수를 적용할 때, 각 요소마다 고유 key 값을 생략한다면 위와 같은 경고를 볼 수 있습니다. 물론 렌더링엔 전혀 문제없습니다.
공식문서에 의하면, Key는
1. React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕고,
2. 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 한다.
“keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity".
즉 key 는 그 값이 변하지 않는, 유일한 식별자의 역할을 가집니다.
고유성 부여를 위해 key 값은, 배열의 각 항목 간 서로를 식별할 수 있게하는 문자열을 사용하는 것이 좋습니다.
대부분 데이터의 ID 를 key 로 사용합니다. (물론 이는 데이터 요소에 ID 프로퍼티가 존재할 때만 가능합니다.)
const todoItems = todos.map( todo =>
<li key={todo.id}>
{todo.text}
</li>
);
key 는 엘리먼트의 변화를 감지한다.
우선 브라우저가 변화를 감지하여 DOM 이 변경되는 과정을 간략하게 살펴봅시다.
1. virtualDOM 에서 변화를 감지합니다. 기존의 컴포넌트는 청록색, 변화가 생긴 컴포넌트는 밝은 녹색으로 표현합니다.
2. 변화가 일어난 virtualDOM 과 realDOM 을 비교하여 새로운 DOM을 연산합니다.
3. 비교 이후, realDOM 은 virtualDOM 과 동일하게 업데이트 됩니다.
위 이미지에서 알 수 있듯이, realDOM은 모든 부분을 업데이는 하는 것이 아닌 변화가 감지된 부분만 업데이트 합니다.
그렇다면 어떤 변화가 생겼을 때, 최소한의 업데이트만 줄 수 있다면 DOM 은 효율적으로 운용될 수 있습니다.
// 기존 컴포넌트 형태
<ul>
<li> React </li>
<li> Vue </li>
<li> Angular </li>
</ul>
// 새로운 list 추가 됐을 때
<ul>
<li> Svelte </li> // <- new item
<li> React </li>
<li> Vue </li>
<li> Angular </li>
</ul>
새로운 list item 으로 <li> Svelte </li> 를 추가해봅시다.
단순히 하나의 아이템만 추가된 것으로 생각할 수 있지만, 리액트는 list 의 전체 순서가 변한 것으로 인지하여 모든 <li> 태그를 리렌더링 하게 된다. 즉 DOM을 비효율적으로 운영하게 됩니다.
위의 예시 코드에선 key 프로퍼티가 없습니다.
만약 <li> 엘리먼트에 각각의 key 속성이 있다면 어떻게 됐을까요?
key가 없을 때는 리스트를 순차적으로 비교하며 변화를 감지합니다.
즉 모든 리스트를 순회, 업데이트하고 나서야, svelte 만 추가된 것을 알게 됩니다.
하지만 key가 존재할 땐, 리액트는 original DOM 과 비교하여 어떤 요소만 변화가 있는지 빠르게 찾아낼 수 있습니다. 즉, 이전처럼 모든 리스트를 순회할 필요 없이, 새롭게 추가된 svelte 만 업데이트 시킬 뿐입니다. key 를 사용하면 기존의 요소는 리렌더링하지 않고 변화가 감지된 요소만 리렌더링하여 효율적인 DOM 사용이 가능합니다.
결론
결국 React 에서 key 를 사용하는 이유는 엘리먼트 혹은 컴포넌트의 변화를 감지하기 위함이고,
그 이유는 효율적인 DOM 사용으로 귀결된다고 생각합니다.
ref:
https://ko.reactjs.org/docs/lists-and-keys.html
https://meganslo.medium.com/why-is-reacts-key-prop-important-b6bd51124270
javatpoint.com (그래프 사진)
'Frontend > React' 카테고리의 다른 글
211124 개발기록: 조건을 걸어 상태 조작하기 (0) | 2021.11.24 |
---|---|
[recoil] Error: Invalid hook call (1) | 2021.06.08 |
React - netlify로 배포하기 (feat. github) (1) | 2021.05.26 |
redux tutorial (0) | 2021.04.29 |
React 리액트 - 중첩 객체의 state 변경 (0) | 2021.02.20 |