리액트의 작동원리 - (1) 재조정 (Reconciliation)

posinity·2023년 3월 27일
0

React

목록 보기
43/58

정의

리액트는 컴포넌트에서 prop이나 state가 변경될 때, 직전에 렌더링된 요소(element)와 새로 반환된 요소를 비교하여 실제 DOM을 업데이트 할지 말지 결정해야 한다. 이때 두 element가 일치하지 않으면 리액트는 새로운 요소로 DOM을 업데이트 하는데, 이러한 프로세스를 reconciliation이라고 한다.

리액트는 선언적이다

React에게 원하는 UI의 상태를 알려주면 DOM이 그 상태와 일치하도록 하기 때문에. 사용할 때 비교 알고리즘 등의 내부 동작은 알 필요가 없기 때문.

비교 알고리즘(Diffing Algorithm)

두 개의 트리를 비교할 때, React는 두 엘리먼트의 루트(root) 엘리먼트부터 비교한다.

엘리먼트의 타입이 다른 경우: 이전 트리를 버리고 완전히 새로운 트리를 구축

    // 이전 트리
    <div>
      <Counter /> 
    </div>

    // 새로운 트리
    <span>
      <Counter />
    </span>

    // 이전 Counter는 버리고 새로운 Counter 사용

DOM 엘리먼트의 타입이 같은 경우: 두 엘리먼트의 속성을 확인하여, 동일한 내역은 유지하고 변경된 속성들만 갱신

    <div className="before" title="stuff" />

    <div className="after" title="stuff" />
    // className만 수정

DOM 노드의 처리가 끝나면, React는 이어서 해당 노드의 자식들을 재귀적으로 처리한다.

자식에 대한 재귀적 처리

DOM 노드의 자식들을 재귀적으로 처리할 때, React는 기본적으로 동시에 두 리스트를 순회하고 차이점이 있으면 변경된 부분을 갱신한다.

// 이전 트리
<ul>
  <li>first</li>
  <li>second</li>
</ul>

// 새로운 트리
<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

→ 위에서부터 비교하다가 새로운 트리에서 third가 생겼으므로

  • third
  • 만 트리에 추가한다.

    자식들이 key를 가지고 있다면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인한다.

    // 이전 트리
    <ul>
      <li key="100">first</li>
      <li key="200">second</li>
    </ul>
    
    // 새로운 트리
    <ul>
    	<li key="300">third</li> // <- 여기!
      <li key="100">first</li>
      <li key="200">second</li>
    </ul>

    → 이렇게 되면, 300 key를 가진 third만 새로운 트리에 새로 추가되고 나머지는 이동만 하게 된다.

    참고자료

    [React] Reconciliation이란? (+ virtual DOM, 리액트는 선언적)

    profile
    문제를 해결하고 가치를 제공합니다

    0개의 댓글