📌 DOM(실제 문서 객체 모델)
: HTML 코드를 웹 브라우저가 해석해서 생성한 객체 모델
- 🟰 HTML markup
- 상속되는 조상이 많아서 복잡하다.
👉 유지보수 비용 많이 듬
// 부모(상위) 요소
const figureElement = document.createElement('figure');
// 자식(하위) 요소
const figcaptionElement = document.createElement('figcaption');
// 요소 간 관계 형성
figureElement.append(figcaptionElement);
// figure 객체의 children에 figcation이 생김
console.dir(figureElement); // figure 객체
// 렌더링
const actualDomElement = document.getElementById('actual-dom');
actualDomElement.append(figureElement);
✨ HTML 태그는 DOM이 아니다.
- HTML 태그는 textContent
- HTML 태그를 웹 브라우저에서 파싱(해석)한게 DOM
📌 Virtual DOM (가상 문서 객체 모델)
: 실제 DOM을 추상화(단순화) 한 DOM의 가벼운 복사본
- 전체 UI를 다시 렌더링하는 대신 변경된 부분만을 업데이트할 수 있다.
- 재조정(Reconcilation) 과정을 통하여 실제 DOM과 동기화 한다.
- UI가 변경을 감지하면 UI를 Virtual DOM으로 렌더링 (실제 화면상 렌더링 되는 것이 아닌 비교를 위한 가상 렌더링)
- 현재 Virtual DOM과 이전 Virtual DOM을 비교해 차이를 계산
- 변경된 부분을 실제 DOM에 반영
* 단순화: 먼저 사물의 특징으로 단순화하여 사물을 인식할 수 있도록 하는 것
// 자식(하위) 요소
const figcationVElement = createElement('figcaption');
// 부모(상위) 요소
const figureVElement = createElement('figure', null, figcationVElement);
console.dir(figureVElement); // object 객체 (단순화됨)
✅ virtual.createElement()
createElement(type, props, child1, child2, ...children)
- props: 속성(attributes)
- child: 해당 요소의 자식 요소(children)
: Virtual DOM의 요소를 생성
- React.createElement()와 유사
// 자식(하위) 요소
const figcationVElement = createElement('figcaption');
// 부모(상위) 요소
const figureVElement = createElement('figure', null, figcationVElement);
// 가상 요소를 실제 DOM 요소로 렌더링
const virtualRootElement = document.getElementById('virtual-dom');
const vRoot = createRoot(virtualRootElement);
vRoot.render(figureVElement);
console.dir(vRoot);
✅ virtual-dom.createRoot()
createRoot(container)
- container: 렌더링을 삽입할 실제 DOM(HTML 태그) 컨테이너
: 새로운 루트(컴포넌트 트리의 최상위 요소)를 생성하고 렌더링
- ReactDOM.createRoot()와 유사
* 선언형 프로그래밍 (Declarative Programming)
- Data + JavaScript Markup = Virtual DOM (VirtualElement Tree)
import { createElement } from "./lib/virtual/index.js";
import { createRoot } from "./lib/virtual-dom/index.js";
// Data
const listData = {
items: [
{ id: "1", title: "Climatology" },
{ id: "2", title: "History of Architecture" },
{ id: "3", title: "Graphics" },
{ id: "4", title: "Building design" },
],
};
// 가상 요소 생성
const listItems = listData.items.map(({ id, title }) => {
// <li> 삽입
const itemElement = createElement(
"li",
{ className: "item" },
// <img> 삽입
createElement(
"img",
{src: `/architectures/architecture-${id}.jpg`, alt: "" }
),
// <span> 삽입
createElement(
"span",
{ className: "content" },
title
),
// <button> 삽입
createElement(
"button",
{type: "button", title: "아이템 이동 (위/아래 화살표 키 활용)"},
// <img> 삽입
createElement(
"img",
{src: "/icons/handle.svg", alt: "아이템 이동 (위/아래 화살표 키 활용)",
})
)
);
return itemElement;
});
console.log(...listItems);
// <ul> 생성
const list = createElement(
'ul',
{ className: 'architectures', lang: 'en' },
...listItems
);
// 가상 DOM 렌더링
const root = createRoot(document.getElementById('virtual-dom'));
root.render(list);
✨ VIRTUAL_ELEMENT_TYPE
: 리액트의 Virtual DOM을 식별하는 데 사용되는 식별자
- 식별
- 리액트가 Virtual DOM 요소인지 아닌지를 식별하는 고유한 속성 - 불변성
- 리액트 내부에서 자동으로 설정되며, 개발자가 직접 변경할 수 없다. - 효율성
- VIRTUAL_ELEMENT_TYPE을 사용하여 실제 DOM에 최소한의 변경만을 적용, 성능 최적화
1️⃣ 리액트에서 createElement를 호출하면 리액트는 실제 DOM의 가벼운 복제본인 Virtual DOM을 만들어낸다.
2️⃣ 이때 Virtual DOM의 고유한 속성인 VIRTUAL_ELEMENT_TYPE 이란 게 만들어지는데, 이걸 기준으로 Virtual Dom인지 아닌지의 여부가 결정된다.
3️⃣ 이 VIRTUAL_ELEMENT_TYPE 은 리액트 내부에서만 사용되는 고유한 값이라 개발자가 수정하거나 임의로 추가해서 Virtual DOM으로 만들어낼 수 없다.
Virtual DOM과 Internals – React
A JavaScript library for building user interfaces
ko.legacy.reactjs.org
문서 객체 모델(DOM) - Web API | MDN
문서 객체 모델(DOM)은 메모리에 웹 페이지 문서 구조를 표현함으로써 스크립트 및 프로그래밍 언어와 페이지를 연결합니다. 이때 스크립트는 주로 JavaScript를 의미하나 HTML, SVG, XML 객체를 문서로
developer.mozilla.org
ReactDOMClient – React
A JavaScript library for building user interfaces
legacy.reactjs.org