Diffing Algorithm
- 두개의 트리를 비교할 때, 리액트는 두 엘리먼트의 root 엘리먼트 부터 비교한다.
- 이 후의 동작은 root 엘리먼트의 타입에 따라 달라진다.
1. DOM 엘리먼트의 타입이 다른 경우
- 두 루트 엘리먼트의 타입이 아예 다르면 (ex.
<a/>
-><img/>
) 리액트는 이전 트리를 버리고 완전히 새로운 트리를 구축한다. - 트리를 버릴 때 이전 DOM 노드들은 모두 파괴된다.
- 컴포넌트 인스턴스는
componentWillUnmount
가 실행된다. - 새로운 트리가 만들어질 때, 새로운 DOM 노드들이 DOM에 삽입된다.
- 그에 따라 컴포넌트 인스턴스는
UNSAFE_componentWillMount()
가 실행되고,componentDidMount()
가 이어서 실행된다. - 이전 트리와 관련된 모든 state 는 사라진다.
2. DOM 엘리먼트의 타입이 같은 경우
- 같은 타입일 경우, 리액트는 두 엘리먼트의 속성을 확인하여 동일한 내역은 유지하고 변경된 속성들만 갱신한다.
- 예를들어 className 만 수정한다던지...
- 컴포넌트가 갱신되면 인스턴스는 동일하게 유지되어 렌더링 간 state 가 유지된다.
- 리액트는 새로운 엘리먼트의 내용을 반영하기 위해, 현재 컴포넌트의 인스턴스의 props 를 갱신한다.
- 이 때 해당 인스턴스에
UNSAFE_componentWillReceiveProps()`, `UNSAFE_componentWillUpdate()`, `componentDidUpdate
를 호출한다.
이 다음으로 render()
메서드가 호출 되고, 비교 알고리즘이 이전 결과와 새로운 결과를 재귀적으로 처리한다.