React 공식 홈페이지 따라하기
React 만들어보기 (7) - virtual DOM
vitamin3000
2025. 1. 27. 14:19
우리가 만든 미니 react에서 virtual DOM 역할을 수행하는 코드는 createElement내에 존재하는
return { tag, props, children}
위 코드이다.(input data의 역할)
이 객체의 특징은 트리 구조를 갖는다는 것이다.
React내에서 UI가 업데이트 될 때 render 메소드가 실행될 것이
export function render(vdom, container) {
container.appendChild(createDom(vdom));
}
이것이 React 입장에서는 이미 기존의 DOM과 DOM으로 만들게된 Virtual DOM 객체를 갖고 있고,
새롭게 업데이트될 DOM도 입력으로 받고 있다
이를 통해 Real DOM의 변경사항과 실제 변경 사항의 차이점을 추적할 때
객체 대 객체로 비교할 수 있는 것이다.
이것은 DOM을 비교하는 것보다 엄청나게 비용이 적은 프로세스이기에 ,
두 객체를 비교해서 다른 점만 실제 Real DOM에 반영한다.
이를 코드로 구현해보면..
export function render(vdom, container) {
container.appendChild(createDom(vdom));
}
export const render = (function() {
let prevDom = null;
return function (vdom, container) {
if (prevDom === null){ //처음 실행된 경우
prevDom = vdom;
}
//diff
// 기존의 것과 비교하는 로직을 작성
// 차이점은 객체 레벨에서의 비교
container.appendChild(createDom(vdom));
}
})();
이때 비교하는 로직을 강의에선 실제로 진행하지 않았지만,
추천해주시는 virtual Dom 라이브러리를 소개하고자 한다.
https://github.com/snabbdom/snabbdom
제시한 example에서 조금 살펴보자면,
const vnode = h(
"div#container.two.classes",
{ on: { click: () => console.log("div clicked") } },
[
h("span", { style: { fontWeight: "bold" } }, "This is bold"),
" and this is just normal text",
h("a", { props: { href: "/foo" } }, "I'll take you places!")
]
);
// Patch into empty DOM element – this modifies the DOM as a side effect
patch(container, vnode);
const newVnode = h(
"div#container.two.classes",
{ on: { click: () => console.log("updated div clicked") } },
[
h(
"span",
{ style: { fontWeight: "normal", fontStyle: "italic" } },
"This is now italic type"
),
" and this is still just normal text",
h("a", { props: { href: "/bar" } }, "I'll take you places!")
]
);
// Second `patch` invocation
patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state
맨 마지막 patch에서 기존의 Dom과 새로운 Dom을 비교하여 새로운 Dom을 생성하는 것을 볼 수 있다.