오늘은 Virtual DOM의 개념을 이해하고 이를 구현하기 위한 createElement 함수를 만들어보았습니다!
Virtual DOM 이란?
Virtual DOM은 실제 DOM(Document Object Model)의 가벼운 복사본이라고 할 수 있습니다. JavaScript 객체 형태로 표현되며, 실제 DOM과 달리 메모리에만 존재하기 때문에 변경 작업이 훨씬 빠릅니다.
실제 DOM 구조가 있다고 가정해보겠습니다.
<div class="container">
<h1 id="title">Hello World</h1>
<p id="content">This is a paragraph</p>
</div>
이것을 Virtual DOM으로 표현하면 다음과 같은 JavaScript 객체가 됩니다.
{
"type": "div",
"props": {
"className": "container"
},
"children": [
{
"type": "h1",
"props": {
"id": "title"
},
"children": [
"Hello World"
]
},
{
"type": "p",
"props": {
"id": "content"
},
"children": [
"This is a paragraph"
]
}
]
}
원리
1. 코드 작성 부분
const element2 = (
<div className="container">
<h1 id="title">Hello World</h1>
<p id="content">This is a paragraph</p>
</div>
);
위 코드는 JSX 문법으로 작성된 코드입니다. 브라우저는 이 JSX를 이해하지 못해서, 바벨(Babel)이 코드를 다음과 같이 변환합니다.
const element2 = createElement('div', { className: 'container' },
createElement('h1', { id: 'title' }, 'Hello World'),
createElement('p', { id: 'content' }, 'This is a paragraph')
);
2. Virtual DOM 생성
위 코드가 실행되면 우리가 만든 createElement 함수에 의해 Virtual DOM 객체가 생성됩니다.
{
type: 'div',
props: { className: 'container' },
children: [
{
type: 'h1',
props: { id: 'title' },
children: ['Hello World']
},
...
]
}
createElement 함수 구현
Virtual DOM을 생성하기 위해 createElement 함수를 구현했습니다.
function createElement(type, props, ...children) {
return {
type,
props: props || {},
children: children.flat(),
};
}
- type: HTML 태그 이름("div", "h1" 등)
- props: 요소의 속성들(className, id 등)
- children: 자식 요소들을 매개변수로 받아 Vritual DOM 객체를 생성합니다.
여러가지 예시로 살펴보기
1. 기본적인 구조
const element1 = (
<div>
<h1>Hello</h1>
<p>World</p>
</div>
);
콘솔 출력 결과:
{
"type": "div",
"props": {},
"children": [
{
"type": "h1",
"props": {},
"children": [
"Hello"
]
},
{
"type": "p",
"props": {},
"children": [
"World"
]
}
]
}
2. 속성이 있는 구조
const element2 = (
<div className="container">
<h1 id="title">Hello World</h1>
<p id="content">This is a paragraph</p>
</div>
);
콘솔 출력 결과:
{
"type": "div",
"props": {
"className": "container"
},
"children": [
{
"type": "h1",
"props": {
"id": "title"
},
"children": [
"Hello World"
]
},
{
"type": "p",
"props": {
"id": "content"
},
"children": [
"This is a paragraph"
]
}
]
}
3. createElement 직접 호출하기
JSX를 사용하지 않고 createElement 함수를 직접 호출할 수도 있습니다.
const test = createElement(
"div",
{ className: "test" },
createElement("h1", null, "Test"),
createElement("p", null, "Content")
);
콘솔 출력 결과:
{
"type": "div",
"props": {
"className": "test"
},
"children": [
{
"type": "h1",
"props": {},
"children": [
"Test"
]
},
{
"type": "p",
"props": {},
"children": [
"Content"
]
}
]
}
4. main.jsx의 전체 코드
/** @jsx createElement */
// 1. createElement 함수 구현
function createElement(type, props, ...children) {
// type: 태그 이름('h1', 'div' 등)
// props: 속성들(class, id 등)
// children: 자식 요소들
return {
type,
props: props || {},
children: children.flat(), // 중첩된 배열 처리를 위해 flat() 추가
};
}
// 2. 댜양한 JSX 예시들 작성
// 2.1 기본 예시
const element1 = (
<div>
<h1>Hello</h1>
<p>World</p>
</div>
);
// 2.2 속성이 있는 예시시
const element2 = (
<div className="container">
<h1 id="title">Hello World</h1>
<p id="content">This is a paragraph</p>
</div>
);
// 3. Virtual DOm 객체 출력 및 구조 분석
console.log("기본 예시의 Virtual DOM 구조");
console.log(JSON.stringify(element1, null, 2));
console.log("속성이 있는 예시의 VIrtual DOM 구조");
console.log(JSON.stringify(element2, null, 2));
// 4. 간단한 테스트
const test = createElement(
"div",
{ className: "test" },
createElement("h1", null, "Test"),
createElement("p", null, "Content")
);
console.log("직접 createELement를 호출한 결과");
console.log(JSON.stringify(test, null, 2));
Virtual DOM을 사용하는 이유
- 성능 최적화: 실제 DOM 조작은 비용이 많이 들지만, Virtual DOM은 JavaScript 객체를 다루는 것이므로 훨씬 빠릅니다.
- 일괄 처리: 여러 변경사항을 Virtual DOM에서 한 번에 모아서 실제 DOM에 적용할 수 있습니다.
- 크로스 플랫폼: Virtual DOM은 브라우저의 DOM에 직접적으로 의존하지 않기 때문에 다양한 환경(ex: React Native)에서 사용할 수 있습니다.
느낀 점
오늘 구현한 createElement 함수를 통해 JSX로 작성한 코드가 어떻게 Virtual DOM 객체로 변환되는지, 그리고 그 구조가 어떻게 되는지 이해할 수 있었습니다. 이는 React가 내부적으로 동작하는 방식을 이해하는 첫 걸음이 되었습니다!_!
'왓에버' 카테고리의 다른 글
Virtual DOM을 실제 DOM으로 렌더링 하기 (0) | 2025.02.05 |
---|---|
컴포넌트 작성과 Virtual DOM 구조 분석 (1) | 2025.01.28 |
React 직접 만들어보기: JSX 이해 및 개발 환경 구축 (0) | 2025.01.27 |