Vanilla Javascript로 가상돔(VirtualDOM) 만들기 | 개발자 황준일
[번역] 리액트에 대해서 그 누구도 제대로 설명하기 어려운 것 - 왜 Virtual DOM 인가?
DOM을 추상화한 Object가 VirtualDOM 입니다. 조금 더 쉽게 말해서 “DOM 처럼 생긴 객체”가 바로 가상돔입니다.
이런 HTML이 있습니다.
<div id="app">
<ul>
<li>
<input type="checkbox" class="toggle" />
todo list item 1
<button class="remove">삭제</button>
</li>
<li class="completed">
<input type="checkbox" class="toggle" checked />
todo list item 2
<button class="remove">삭제</button>
</li>
</ul>
<form>
<input type="text" />
<button type="submit">추가</button>
</form>
</div>
이를 가상돔으로 표현하면 다음과 같습니다.
function virtualDom(type, props, ...children) {
return { type, props, children: children.flat() }
}
const result = (
virtualDom('div', { id: 'app' },
virtualDom('ul', null,
virtualDom('li', null,
virtualDom('input', { type: 'checkbox', className: 'toggle' }),
'todo list item 1',
virtualDom('button', { className: 'remove' }, '삭제')
),
virtualDom('li', { className: 'completed' },
virtualDom('input', { type: 'checkbox', className: 'toggle', checked: true }),
'todo list item 2',
virtualDom('button', { className: 'remove' }, '삭제')
),
),
virtualDom('form',
virtualDom('input', { type: 'text' }),
virtualDom('button', { type: 'submit' }, '추가'),
)
)
);
보통 virtualDom
대신 h
로 표현합니다.
function h(type, props, ...children) {
return { type, props, children: children.flat() }
}
const result = (
h('div', { id: 'app' },
h('ul', null,
h('li', null,
h('input', { type: 'checkbox', className: 'toggle' }),
'todo list item 1',
h('button', { className: 'remove' }, '삭제')
),
h('li', { className: 'completed' },
h('input', { type: 'checkbox', className: 'toggle', checked: true }),
'todo list item 2',
h('button', { className: 'remove' }, '삭제')
),
),
h('form',
h('input', { type: 'text' }),
h('button', { type: 'submit' }, '추가'),
)
)
);
그리고 위의 코드는 다음과 같은 객체로 변환답니다.
{
"type": "div",
"props": { "id": "app" },
"children": [
{
"type": "ul",
"props": null,
"children": [
{
"type": "li",
"props": null,
"children": [
{
"type": "input",
"props": { "type": "checkbox", "className": "toggle" },
"children": []
},
"todo list item 1",
{
"type": "button",
"props": { "className": "remove" },
"children": [ "삭제" ]
}
]
},
{
"type": "li",
"props": { "className": "completed" },
"children": [
{
"type": "input",
"props": { "type": "checkbox", "className": "toggle", "checked": true },
"children": []
},
"todo list item 2",
{
"type": "button",
"props": { "className": "remove" },
"children": [ "삭제" ]
}
]
}
]
},
{
"type": "form",
"props": {
"type": "input",
"props": { "type": "text" },
"children": []
},
"children": [
{
"type": "button",
"props": { "type": "submit" },
"children": [ "추가" ]
}
]
}
]
}
코드를 보면 알겠지만, 가상돔(VirtualDOM)은 거창한게 아니라 DOM의 형태를 본따 만든 객체 덩어리입니다. 사실 가상돔(VirtualDOM)만 쓴다고해서 드라마틱한 변화가 생기는 것은 아닙니다.