리액트 프레임워크를 구성하는 3요소는 가상DOM, JSX, 컴포넌트이다.
이중 가상 DOM부터 알아보겠다.
react 와 react-dom
리액트 플젝의 경우, 항상 react와 react-dom이 필요하다.
react는 컴포넌트와 jsx, 리액트 훅 등 렌더러에 무관한 기능 (= 환경과 무관하게 공통 사용하는기능) 을 제공
react-dom은 앱이 동작하는 환경에 종속적인 기능을 제공하는데 특화된 패키지
다음과 같은 구조라고 보면 된다. XML 마크업 언어를 사용한다.
document.createElement(요소); --xml요소를 만듬
document.appendChild(부모요소); --xml에서 부모요소의 자식 요소를 가리킬 때 사용
document.getElementById(아이디명); --xml요소에서 아이디값을 가지고 내용을 불러옴
다음과 같은 기본 자바스크립트 문법을 알고 있다고 가정, 가상 DOM과 물리 DOM의 다른 점을 확인해본다.
자바스크립트는 물리 DOM을 사용하고, 리액트는 가상 DOM을 사용하는데, 같은 내용을 출력한다고 가정하고 내용을 비교해본다.
물리 DOM
import React from 'react'
let pPhysicalDOM = document.crateElement('p')
pPhysicalDOM.innerText = 'Hello physical DOM world!'
document.body.appendChild(pPhysicalDOM)
가상 DOM
import React from 'react'
import ReactDOM from 'react-dom/client'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
const pVirtualDOM = React.createElement('p', null, 'Hello virtual DOM world!')
root.render(pVirtualDOM)
왜 이렇게 복잡하게 구현하는지, 처음에는 이해가 가지 않았다.
가상 DOM트리가 물리 DOM 트리로 처음 바뀔때는 괜찮지만, 코드에서 'Hello virtual(physical) DOM world'가 아닌 'Welcome to our site!'를 나오게 해야한다면? createElement와 appendChild의 문제가 아니라, <p>요소 안의 텍스트를 찾아서 바꾸어야 하기 때문에 문제가 생긴다.
위의 경우 간결하게 <p>라고 사용했지만, 보통은 <p id=' 아이디명 ' class= '클래스명' ...> 이런식으로 속성을 명시하기 때문에 물리적으로는 간단히 변경하기 어려운 것이다.
가상DOM의 경우 , createRoot에서 아이디를 생성하고, createElement에서 따로 요소와 내용을 생성한다. 그리고 root.render로 DOM에 합치게 (?)되는 구조라고 볼 수 있다.
javascript에서 물리적으로 이거입력!저거입력! create! 이런식으로 만들었는데,
가상DOM에서 root.render로 로봇마냥 합치는 구조가 신기했다 👍
가상DOM을 겉핥기 식으로 이해한 느낌이다.