[깃허브 링크]
React의 작동 원리
let virtualDOM = null;
function render(reactEl, containerDOMEl) {
const newVirtualDOM = createVirtualDOM(reactEl);
if (!virtualDOM || virtualDOMHasChanged(virtualDOM, newVirtualDOM)) {
updateRealDOM(containerDOMEl, newVirtualDOM);
}
virtualDOM = newVirtualDOM;
}
function createVirtualDOM(reactEl) {
return {
type: reactEl.type,
props: reactEl.props,
children: reactEl.children,
subChildren: reactEl.subChildren,
};
}
function virtualDOMHasChanged(oldVDOM, newVDOM) {
const childrenChanged = oldVDOM.children !== newVDOM.children;
const subChildrenChanged = oldVDOM.subChildren !== newVDOM.subChildren;
if (childrenChanged) {
console.log(
"`children` has changed from",
oldVDOM.children,
"to",
newVDOM.children
);
}
if (subChildrenChanged) {
console.log(
"`subChildren` has changed from",
oldVDOM.subChildren,
"to",
newVDOM.subChildren
);
}
return childrenChanged;
}
function updateRealDOM(containerDOMEl, virtualDOM) {
console.log("실제 DOM 업데이트!");
const domEl = document.createElement(virtualDOM.type);
domEl.innerText = virtualDOM.children;
domEl.setAttribute("href", virtualDOM.props.href);
containerDOMEl.innerHTML = "";
containerDOMEl.appendChild(domEl);
}
const reactEl = {
type: "a",
props: {
href: "https://www.naver.com",
},
children: "Google Link",
subChildren: "Sub Link",
};
const containerDOMEl = document.getElementById("root");
document.getElementById("updateMain").addEventListener("click", () => {
reactEl.children = "Updated Main Link";
render(reactEl, containerDOMEl);
});
document.getElementById("updateSub").addEventListener("click", () => {
reactEl.subChildren = "Updated Sub Link";
render(reactEl, containerDOMEl);
});
render(reactEl, containerDOMEl);
위의 코드에서는 React가 어떻게 변경사항을 파악하고 어떻게 실제 DOM에 업데이트하는지에 대한 기본적인 원리를 보여줍니다.
우선, 주목해야 할 부분은 두 가지입니다.
1. 첫 번째는 reactEl 객체입니다.
이 객체는 일반적으로 React에서 사용되는 JSX의 구조를 가진 단순한 JavaScript 객체로 생각하실 수 있습니다. 실제 React에서는 JSX 문법을 사용하지만, 그 JSX는 바벨(Babel)과 같은 트랜스파일러에 의해 이러한 JavaScript 객체로 변환됩니다.
2. 두 번째 주목해야 할 부분은 containerDOMEl입니다.
이 변수는 React에서 실제 DOM 요소를 참조하는 역할을 합니다. 이를 '루트 DOM 노드'라고도 부르며, React 애플리케이션은 이곳에 마운트되게 됩니다.
이 두 요소를 render 함수에 전달하면, 함수는 다음과 같은 작업을 수행합니다
1. reactEl 객체를 기반으로 새로운 가상 DOM을 생성합니다.
2. 이전의 가상 DOM과 새로운 가상 DOM을 비교하여 차이점을 파악합니다. 이 차이점 파악 과정을 'diffing'이라고 합니다.
3. 만약 변경사항이 있다면, 해당 변경사항만 실제 DOM에 반영합니다.
이 예제에서 특이한 점은 subChildren입니다. virtualDOMHasChanged 함수 내에서는 subChildren의 변경사항은 인식되지만, 실제로 DOM 업데이트의 기준으로는 삼지 않습니다. (예시코드에서는 오직 children의 변경사항만 인식하고있습니다.)
따라서 subChildren이 변경되더라도 실제 DOM은 업데이트되지 않습니다.
물론 실제 React의 동작 방식과는 다르지만, 이를 통해 React 기본 개념을 간단하게 이해할 수 있습니다.
'OLD > React' 카테고리의 다른 글
[React] React 리렌더링의 모든 것 (1) | 2024.03.24 |
---|---|
[React 19] 2024년 5월 react 19 발표? (0) | 2024.02.18 |
[ React ] react-router loader vs react-query useQuery (0) | 2023.08.22 |
[React] 여전히 create-react-app을 사용 해야 할까? (CRA vs VITE) (0) | 2023.05.22 |
[React] React Redux_03 (Redux와 SideEffect & Async) (0) | 2023.03.08 |