1. 각기 서로 다른 두 요소는 다른 트리를 구축한다.
2. 개발자가 제공하는 key 프로퍼티를 가지고, 여러 번 렌더링을 거쳐도 변경되지 말아야 하는 자식 요소가 무엇인지 알아낼 수 있다.
React는 위의 두 가정을 가지고 새로운 휴리스틱 알고리즘(Heuristic Algorithm)을 구현해내었다. 실제 이 두 가정은 거의 모든 실제 사용 사례에 들어맞게 됩니다. 여기서 React는 비교 알고리즘(Diffing Algorithm)을 사용한다.
*휴리스틱(Heuristic)이란 불충분한 시간이나 정보로 인하여 합리적인 판단을 할 수 없거나, 체계적이면서 합리적인 판단이 굳이 필요하지 않은 상황에서 사람들이 빠르게 사용할 수 있게 보다 용이하게 구성된 간편한 추론의 방법을 뜻한다.
Diffing Algorithm
React는 기존의 가상 DOM 트리와 새롭게 변경된 가상 DOM 트리를 비교할 때, 트리의 레벨 순서대로 순회하는 방식으로 탐색한다. 즉, 같은 레벨(위치)끼리 비교한다는 뜻이다. 이는 너비 우선 탐색(BFS)의 일종이라고 볼 수 있다.
다른 타입의 DOM 엘리먼트인 경우
DOM 트리는 각 HTML 태그마다 각각의 규칙이 있어 그 아래 들어가는 자식 태그가 한정적이라는 특징이 있다. 자식 태그의 부모 태그 또한 정해져 있다는 특징이 있기 때문에, 부모 태그가 달라진다면 React는 이전 트리를 버리고 새로운 트리를 구축한다.
같은 타입의 DOM 엘리먼트인 경우(속성만 바뀌는 경우)
타입이 바뀌지 않는다면 React는 최대한 렌더링을 하지 않는 방향으로 최소한의 변경사항만 업데이트한다. 이것이 가능한 이유는 앞서 React가 실제 DOM이 아닌 가상 DOM을 사용해 조작하기 때문이다. 업데이트할 내용이 생기면 virtual DOM 내부의 프로퍼티만 수정한 뒤, 모든 노드에 걸친 업데이트가 끝나면 그 때 단 한번 실제 DOM으로의 렌더링을 시도한다.
자식 요소가 다른 경우
React는 자식 노드를 순차적으로 위에서부터 아래로 비교하면서 바뀐 점을 찾는다(재귀적). 이러한 동작방식에 대해 고민하지 않고 리스트의 처음에 엘리먼트를 삽입하면, 아래의 두 자식노드는 유지시켜도 된다는 것을 깨닫지 못하고 전부 버리고 새롭게 렌더링 해버린다. 이는 매우 비효율적인 동작 방식이다. 그래서 React는 이 문제를 해결하기 위해 key라는 속성을 지원한다. 이 key 속성에는 보통 데이터 베이스 상의 유니크한 값(ex. Id)를 부여해주면 된다. key는 전역적으로 유일할 필요는 없고, 형제 엘리먼트 사이에서만 유일하면 된다.
만약 이런 유니크한 값이 없다면 최후의 수단으로 배열의 인덱스를 key를 사용할 수 있지만 추천하지는 않는다.
'프로그래밍 > React' 카테고리의 다른 글
React - useCallback (0) | 2023.05.23 |
---|---|
React - useMemo (0) | 2023.05.22 |
React - Virtual DOM (0) | 2023.05.22 |
React - Styled Components (0) | 2023.04.19 |
React - Side Effect / Pure Function (0) | 2023.04.03 |
댓글