티스토리 뷰
Reconciliation이란 코드에 diff가 생겼을 때 DOM에 반영하는 로직이다. 공식 독스에서 크게 2가지를 중심으로 설명한다. 하나는 루트 엘리먼트의 타입이고, 하나는 key 어트리뷰트다.
Type diff of root element
- 루트 엘리먼트의 type이 다른 경우
- DOM element인지 React element인지를 불문하고 트리를 tear down하고 rebuild한다. (e.g.
<img>와 <button>, <Comment />와 <Article />
) - DOM이라면 해당 element를 제거하고 새로 삽입하고, React component라면 unmount했다가 새로 만들어서 mount한다.위 같은 경우 자식 컴포넌트는 동일하지만 root element의 type이 div와 span으로 다르므로, Counter 컴포넌트는 언마운트하고 새로 만들어서 마운트한다.
<div> <Counter /> </div> <span> <Counter /> </span>
- DOM element인지 React element인지를 불문하고 트리를 tear down하고 rebuild한다. (e.g.
- 루트 엘리먼트의 type이 같은 경우
- DOM element인데 type이 같은 경우, attribute를 확인하고 다른 attribute만 기존의 DOM에다가 업데이트한다.
- React Component의 type이 같은데(=같은 컴포넌트인 경우) props, state에 변경사항이 있는 경우에는 re-rendering을 한다. (Unmount X)
Keys
<ul>
<li>first</li>
<li>second</li>
</ul>
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
이런 경우에는 마지막 li 컴포넌트만 삽입하면 된다.
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
하지만 이렇게 순서가 뒤바뀌는 경우에 리액트는 모든 li 컴포넌트를 바꿔버린다. 이는 비효율적이다. 새로 추가된 코네티컷 li만 추가할 수 없을까?
이런 문제를 해결하기 위해서 리액트는 key라는 attribute를 제공한다.
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
이렇게 key 어트리뷰트를 주면 리액트는 key가 2014인 li가 새로운 엘리먼트라고 인지하고, key가 2015와 2016인 것은 mutate하지 않고 그냥 위치를 옮기기만 한다.
그래서 이 key는 Id와 같은 역할을 하므로 고유해야 하고, 되도록 변하지 않는 것이어야 한다. 예를 들어 comments를 불러오는 API를 사용해서 map으로 컴포넌트를 나열할 때, key를 array index로 준다면, 다음에 렌더링될 때에는 key와 그 내용물이 맞지 않을 수 있다. 절대로 re order되지 않는 경우에는 괜찮을 수 있지만 느릴 것이다. (As a last resort, you can pass an item’s index in the array as a key. This can work well if the items are never reordered, but reorders will be slow.)
그래서 되도록 index를 key로 주는 것은 예상하지 못한 결과를 낼 수도 있으므로 피해야 한다.
Ref
'공부일지(TIL) > JS Framework + Library' 카테고리의 다른 글
[React] useEffect에서 data fetch하기 (0) | 2021.11.07 |
---|---|
[React] Component Composition (0) | 2021.07.26 |
[Redux] Redux랑 RxJS 같이 사용하기 (feat. Redux-Observable) (0) | 2021.04.23 |
[React] re-render (0) | 2021.04.12 |
[React] useImperativeHandle의 장점 (1) | 2021.03.16 |
- Total
- Today
- Yesterday
- Redux
- GIT
- c언어
- Conflict
- 제네릭스
- Prefix Sums
- Java
- SQL
- 리덕스
- 인스턴스
- 개발 공부
- Data Structure
- getter
- linkedlist
- 포인터 변수
- rxjs
- jQuery
- Session
- 자바
- 깃
- JavaScript
- react
- package.json
- youtube data api
- this
- 알고리즘
- useEffect
- CSS
- oracle
- til
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |