React의 재조정(Reconciliation)에 대해 정리해보려 합니다.
여기서 말하는 재조정에서는 diffing 알고리즘을 어떻게 정의했는지에 관한 것입니다.
diffing 알고리즘에에 따라 가상 DOM과 실제 DOM의 차이를 판단합니다.
그리고 변경이 필요한 부분만 대체가 되는 것입니다.
두개의 가정을 먼저 인지하여야 합니다.
- 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
- 개발자가 key prop을 통해, 어떤 자식 element가 변경되지 않아야 하는지를 표시해 줄 수 있다.
diffing 알고리즘
엘리먼트의 타입이 다른경우
리액트에서는 두 개의 트리를 비교할때, 두 엘리먼트의 root 엘리먼트부터 비교를 하게 됩니다.
이 root 엘리먼트가 다르다면 root 엘리먼트를 포함한 트리는 변경됩니다.
<div>
<Counter />
</div>
<p>
<Counter />
</p>
위의 경우에서 div -> p 로 루트 엘리먼트의 타입이 변경되었습니다.
가차없이 이전의 Counter는 사라집니다. 이전 트리에 연관된 state들도 모두 사라집니다.
엘리먼트의 타입은 같은데 속성만 다른 경우
<div className="before" title="stuff" />
<div className="after" title="stuff" />
<div style={{color: 'red', fontWeight: 'bold'}} />
<div style={{color: 'green', fontWeight: 'bold'}} />
두 개의 case모두 엘리먼트의 타입은 같지만 속성(className, color) 만 변경되었습니다.
이러한 경우에는 동일한 내역은 유지하고 변경된 속성들만 갱신합니다.
targeting 중인 DOM node의 갱신이 끝나면 자식들을 재귀적으로 처리합니다.
자식 엘리먼트의 key값이 다른 경우
이 글을 읽으신다면 배열 요소를 jsx로 리턴을 할때 key를 넣어주지 않아서 warning이 뜨신 경험이 있으실 겁니다.
key 값을 넣어주지 않는다면 default로 index가 key값으로 들어갑니다.
배열 요소의 끝에 push를 해줄때는 문제가 없습니다. Index가 변경되지 않기 때문입니다.
문제는 unshift 입니다.
기존에 위치하고 있던 친구들의 index가 바뀌어 버려 불필요한 렌더링을 해주어야 되거나 의도한 대로 화면에 표시가 되지 않을 수 있습니다.
key값에 index를 넣지 않아야 하는 이유에 관하여는 이전에 작성한 글이 있습니다.
2022.04.02 - [Frontend/React] - React keys
React에서는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인합니다.
<ul>
<li key="2014">2014</li>
<li key="2015">2015</li>
</ul>
<ul>
<li key="2013">2013</li>
<li key="2014">2014</li>
<li key="2015">2015</li>
</ul>
위의 코드에서는 Key값을 추가해주었고 key값으로 인해 React에서는 기존의 2014, 2015 key값을 가진 엘리먼트 들은 위치만 이동시키면 된다는 것을 알수 있습니다.
이 key는 같은 형제 노드에서만 유일하면 됩니다!!
출처: https://ko.reactjs.org/docs/reconciliation.html
'Frontend > React' 카테고리의 다른 글
React Redux-saga's work flow from component 🙋♂️ (0) | 2022.04.19 |
---|---|
React Jsx 🌱 (0) | 2022.04.18 |
React hook 🌱 (0) | 2022.04.14 |
React 연속된 요청 useEffect 내에서 처리하기 (useEffect, suspense) (0) | 2022.04.10 |
React suspense (1) | 2022.04.10 |