Warning: Each child in an array or iterator should have a unique "key" prop ...
이라는 경고 문구가 자주 뜨길래, 이 문제를 해결하고 가야겠다는 생각이 들었다.
리액트는 HTML 요소들 중에서 변경된 부분만을 선택해서 리렌더링 할 수 있다. 이 때 가상 돔을 만들어 가볍게 이 문제를 해결한다. DOM과 비슷한 기능을 하는 자바스크립트 객체를 만들어서, 하나는 바뀌기 전의 DOM의 모습을, 다른 하나는 바뀌고 난 후의 DOM의 모습 총 두 개의 가상 돔을 만들어서 비교하게 되는데, 이 때 이 비교를 수행할 때 사용하는 알고리즘을 diffing 알고리즘이라 한다.
이 때 이 diffing 알고리즘의 시간 복잡도를 O(n)으로 만들어주기 위해 두 가지 가정을 도입했다.
이를 기반으로 diffing 알고리즘을 더 깊이 들어가본다.
리액트는 두 개의 트리(가상 돔)를 비교할 때 두 엘리먼트의 루트 엘리먼트부터 비교한다. 그리고 그 자식 노드들을 재귀적으로 처리한다.
DOM 엘리먼트의 타입이 다른 경우
변경 전
<div>
<Counter />
</div>
변경 후
<span>
<Counter />
</span>
이 경우, 리액트는 이전 트리를 버리고 완전히 새로운 트리를 만든다. 이전 DOM 노드들은 모두 파괴되고 새로운 노드가 마운트된다.
DOM 엘리먼트의 타입이 같은 경우
이 경우에는 동일한 내역은 유지하고 변경된 속성들만 갱신한다.
변경 전
<div className="before" title="stuff" />
변경 후
<div className="after" title="stuff" />
이 경우에는 className만 수정한다.