import React from 'react'
import ReactDOM from 'react-dom'
리액트 앱을 설치하면, index.tsx파일에서 항상 이 패키지들을 불러오는 것을 알 수 있을 거에요.
리액트 프로젝트는 항상 react와 react-dom패키지를 필요로 합니다.
그리고 둘의 경계에는 가상 DOM이라는 매커니즘이 자리잡고 있습니다.
가상돔을 이야기하기에 앞서, DOM(Document Object Model, 문서 객체 모델)이란 무엇일까요?
웹 브라우저는 HTML형식의 문자열을 화면에 출력하려고 할 때, 이를 파싱(parsing)하여 어떤 특별한 자바스크립트 객체 모델로 바꿉니다. 이것이 DOM입니다.
앞서 설명한 DOM을 뒤에 나올 가상DOM과 구분하여, 물리 DOM이라고 부르겠습니다.
리액트를 사용하지 않고, 자바스크립트만 사용해서 물리DOM을 직접 조작해보겠습니다.
// p태그 엘리먼트 생성
let pPhysicalDOM = document.createElement('p')
pPhysicalDOM.innerText = 'Hello physicalDOM world!'
// body태그 엘리먼트에 부착 (랜더링)
document.body.appendChild(pPhysicalDOM)
import React from 'react'
import ReactDOM from 'react-dom'
// 가상DOM 엘리먼트 생성
const pVirtualDOM = React.createElement('p', null, 'Hello virtual DOM world!') // 두번째 요소는 타입지정(옵션)
// 'root'라는 id의 엘리먼트 안에 가상DOM 부착
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
// 가상DOM을 물리DOM으로 전환(랜더링)
root.render(pVirtualDOM)
리액트는 React.CreateElement 함수로 다양한 HTMl요소를 가상 DOM 트리 구조로 구현한 뒤, render()메서드가 호출되는 순간 이 가상 DOM트리를 물리 DOM 트리로 변환해줍니다.
코드를 그림으로 표현하면 다음과 같습니다.
이 의문은 처음 랜더링될 때만을 생각하면 타당할 수 있습니다.
하지만 최초 랜더링 이후 가상 DOM 트리 구조에 변화가 생겨, 이 변화를 사용자에게 알리기 위해 다시 랜더링되는 상황을 생각하면 달라집니다.
- 가상DOM은 물리 DOM의 가벼운 복사본으로, 리액트는 변경 이전 트리와 변경 이후 트리 두가지 복사본을 항상 갖고 있는다. 그리고 이 둘을 비교하여 변경된 부분만 빠르게 업데이트합니다.
- 리액트는 엘리먼트마다 중복되지 않는 고유한 id(key)를 부여하여, HTML엘리먼트가 매우 많아질 때에도 이를 효과적으로 관리할 수 있습니다.
Do it! 리액트 모던 웹 개발 with 타입스크립트