티스토리 뷰
Diffing Algorithm
- React의 Diffing 알고리즘은 Virtual DOM을 효율적으로 업데이트하기 위해 사용됩니다.
- 이 알고리즘은 이전 가상 DOM 트리와 현재 가상 DOM 트리를 비교하여 변경된 부분을 식별하고 최소한의 DOM 조작으로 업데이트합니다.
- React는 기존의 가상 DOM 트리와 새롭게 변경된 가상 DOM 트리를 비교할 때, 트리의 레벨 순서대로 같은 레벨끼리 비교하는 일종의 너비 우선 탐색(BFS)을 사용합니다.
- 요소들을 비교 시, 만약 부모의 요소의 타입이 바뀌었다면 자식들은 기존의 컴포넌트는 완전히 언마운트하고, 새로운 컴포넌트로 다시 마운트합니다. 이는 HTML 태그마다 가지는 자식 태그가 일부 제한된기 때문입니다.
<ul>
<li/> //ul태그는 li만 자식으로 가집니다.
</ul>
<p>
<p/> //p태그안에 p태그를 사용할 수 없습니다.
</p>
- 그러나 타입이 변경없이 값이나 속성만이 바뀌었다면 최소한의 변경 사항만 업데이트합니다.
- 이때, 하나의 DOM 노드를 처리한 뒤 React는 뒤이어서 해당 노드들 밑의 자식들을 순차적으로 동시에 순회하면서 차이가 발견될 때마다 변경하는 것을 재귀적으로 처리한다고 합니다.
//className이 before인 컴포넌트
<div style={{color: 'red', fontWeight: 'bold"}} title="stuff" />
//className이 after인 컴포넌트
<div style={{color: 'green', fontWeight: 'bold"}} title="stuff" />
//변경시 color속성을 사용하는 모든 자식요소를 순회하면서 변경한다
키(key)의 중요성
- 흔히 map으로 컴포넌트를 반환할때 키를 부여하라는 에러를 받았을 것이다.
- 이는 재귀적 처리의 단점을 보완하기 위한 조치이다.
- 만약 자식 요소가 2개인 부모에 새로운 자식을 추가할 경우, 위에서 아래로 순차적으로 비교하기에 맨 뒤가 아니라 맨 처음에 추가하면 이전에 기억하던 순서와 자식 리스트 전체가 바뀌었다고 판단합니다.
- 때문에 기존의 컴포넌트를 언마운트하고, 새로 다시 마운트하는 비 효율이 발생합니다.
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
//자식 엘리먼트를 처음에 추가합니다.
<ul>
<li>Connecticut</li>// 기존에 존재하던 <li>Duke</li>가 아니기에 리스트 전체가 변경됬다고 판단
<li>Duke</li>
<li>Villanova</li>
</ul>
- 만약 자식 노드들이 이 key를 갖고 있다면, React는 그 key를 이용해 기존 트리의 자식과 새로운 트리의 자식이 일치하는지 아닌지 확인할 수 있습니다.
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
//key가 2014인 자식 엘리먼트를 처음에 추가합니다.
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
- 위에 예시로 설명하면, 순서가 바뀌었지만 key가 2015가 아닌 2014가 왔기에 이전과 동일한 요소가 아닌 새롭게 추가된 요소라고 인식할 수 있습니다.
- 따라서 React는 기존의 동작 방식대로 다른 자식 엘리먼트는 변경하지 않고 추가된 엘리먼트만 변경합니다.
- key는 고유한 값을 주로 사용하는데, 전역적으로 유일할 필요는 없고, 형제 엘리먼트 사이에서만 유일하면 되기에 배열의 인덱스도 key로 사용할 수 있습니다.
'개발 > React' 카테고리의 다른 글
Custom Hooks (0) | 2023.05.22 |
---|---|
React Hooks(useMemo, useCallback) (0) | 2023.05.20 |
가상 DOM (1) | 2023.05.19 |
Redux Toolkit (0) | 2023.04.26 |
redux의 구조 (0) | 2023.04.24 |
댓글