🤵 React에서 key prop이 하는 역할이 무엇일까요? (기억이 정확하지 않지만 이런 느낌의 질문..)
👩 가상돔을 비교하는 과정에서 쓰일 것 같습니다..
React Element는 React 앱의 가장 작은 단위이면서 불변객체이다. 불변객체의 특성 상 엘리먼트 생성 이후에는 자식이나 속성의 변경이 불가하다. 따라서 UI를 업데이트하려면 새로운 엘리먼트 객체를 만들어서 ReactDOM.render()
로 새로 렌더링해 주어야 한다.
React DOM은 새로 그리는 화면을 최소화하기 위해서, 렌더링이 일어날 때, 엘리먼트를 이전 엘리먼트와 비교한 다음 다시 그려야 할 경우에만 DOM을 업데이트한다. React에서는 Diffing Algorithm에 따라 변경 전, 후의 React 엘리먼트 트리를 비교하여 가장 효과적으로 UI를 갱신할 방법을 찾는다.
React Diffing Algorithm
React Diffing Algorithm
은 아래 두 가지를 가정한다.
- 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
- 개발자는
key
prop을 지정하여 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할 지 표시한다.
Diff Algorithm은 아래와 같은 방식으로 진행된다.
DOM 엘리먼트 타입이 다르다면
예를 들어, <div>
엘리먼트가 <a>
엘리먼트로 바뀌는 경우, 트리 전체를 다시 구축한다. 이전의 DOM 노드들은 모두 파괴된다.
DOM 엘리먼트 타입이 같다면
- 두 엘리먼트의 속성을 확인해서 변경된 속성만 갱신한다.
- style 속성 안의 변경된 속성만을 갱신한다.
- 렌더링 전, 후에 엘리먼트가 가지고 있던 state는 유지된다.
DOM 노드의 자식 요소들을 처리하기 위하여 자식 리스트를 순회하며 비교하고, 차이점이 있다면 변경된 엘리먼트를 생성한다. 이 때, 자식 요소에 key prop 값을 주지 않은 상황에서, 만약 어떤 엘리먼트가 자식 리스트 사이에 새로 삽입되었다면, 그 엘리먼트가 삽입된 것으로 인식하지 못하고 해당 엘리먼트 이후의 모든 엘리먼트가 변경된 것으로 인식하여 요소를 다시 만들어 렌더링할 것이다. 이런 상황은 성능에 악영향을 준다.
따라서 각 자식 요소를 고유하게 인식하게 하기 위하여 자식 엘리먼트에는 고유한 key
prop을 주는 것이 좋다. 보통 그 엘리먼트에 들어가는 데이터의 ID 값을 key
prop에 전달한다. Diffing Algorithm에서 key
prop을 사용하여 자식 엘리먼트를 비교하는 방식은 아래와 같다.
- key를 통해 기존 트리와 이후 트리의 자식이 일치하는지 확인하고, 어떤 엘리먼트가 변경되거나 추가, 삭제되었는지 확인한다.
- key는 자식들 간의 비교를 위한 것이므로 형제들 사이에서만 유일하면 되고, 전역에서 유일할 필요는 없다.
- 배열의 인덱스를 key로 사용하는 것은 적절하지 않을 수 있다. 배열은 재배열되었지만 컴포넌트의 위치는 변경되지 않거나 의도치 않은 방식으로 배열되는 경우가 있을 수 있다.