가상 DOM 이해하기

가상 DOM 이해하기

Created
May 6, 2024
Tags
React

리액트 동작 원리를 알아보자. 리액트를 구성하는 기본 3요소는 가상 DOM, JSX 구문, 그리고 컴포넌트이다.

가상 DOM

가상 DOM(Virtual DOM)은 실제 DOM의 가벼운 복사본이라고 생각할 수 있다. 가상 DOM은 메모리에 존재하며, 리액트는 가상 DOM을 사용하여 실제 DOM과의 차이를 계산하고 최소한의 변경만을 실제 DOM에 반영하여 효율적으로 UI를 업데이트한다. DOM에 대한 내용은 여기서 자세하게 다루고 있다.

리액트 프로젝트를 생성해보면 알겠지만, reactreact-dom 패키지가 항상 함께 설치된다.

  • react: 컴포넌트 기반 구조를 사용하여 UI를 구성할 수 있다. 선언적인 구문과 가상 DOM을 활용하여 효율적인 UI 개발을 가능하게 한다.
  • react-dom: 리액트 애플리케이션과 실제 DOM을 연결하는 역할이다. 리액트는 가상 DOM을 사용하여 UI를 효율적으로 관리하고, react-dom은 이를 실제 DOM에 반영해서 화면에 렌더리한다.
💡
즉, react 패키지는 UI를 작성하고 관리하는 데 필요한 주요 기능을 제공하며, react-dom 패키지는 리액트 애플리케이션을 실제 DOM에 렌더링하는 데 사용된다.

그리고, react-dom 패키지 안에는 react-dom/client, react-dom/server, react-native 등 렌더러(Renderer)라고 하는 패키지가 포함되어 있다. 이는 애플리케이션이 동작하는 환경(플랫폼)에 종속적인 기능을 제공하는 데 특화된 패키지이다.

  • react-dom/client: 웹 브라우저에서 클라이언트 측 렌더링을 담당. CSR(Client-Side Rendering) 방식 동작.
  • react-dom/server: 서버 측 렌더링을 담당. SSR(Server-Side Rendering) 방식 동작
  • react-native: 모바일 애플리케이션을 개발하기 위한 프레임워크.

렌더링

DOM 객체를 웹 브라우저 화면에 나타나게 하는 것을 렌더링(Rendering)이라고 한다.

1. JavaScript만 사용하는 DOM

let p = document.createElement("p"); // <p> 요소 생성
document.body.appendChild(p); // <p> 요소를 <body>의 마지막 자식 요소로 추가하고 렌더링
  • HTML 문서의 실제 요소들을 직접 수정하고 새로운 요소를 추가하는 방식이다. document.createElement를 사용하여 요소를 생성하고,
  • appendChild를 사용하여 해당 요소를 문서에 추가한다. 이러한 과정을 통해 DOM을 동적으로 조작하여 UI를 생성하고 업데이트한다.

2. React를 사용하는 가상 DOM

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
const virtualDOM = React.createElement('p', null, 'Hello Virtual DOM World!');
root.render(vertualDOM);

// 실제 index.tsx
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • 리액트에서는 React.createElement 또는 JSX 문법을 사용하여 가상 DOM 요소를 생성한다.
  • 그런 다음, root.render를 사용하여 이 가상 DOM을 실제 DOM에 렌더링한다. 그런데 root.render는 변환한 가상 DOM 객체를 부착(append)할 실제 DOM 객체가 필요하다. 즉, 렌더링될 실제 DOM 요소를 지정해주어야 한다.
  • document.getElementById: 이 메서드는 이미 생성된 특정 DOM 객체를 찾아주는 역할을 한다. 위 코드에서는 id 속성 값이 rootDOM 객체를 찾나낸다.
  • ReactDOM.createRoot: 이 함수를 사용하여 루트 렌더링 컨테이너를 생성하면, 리액트 애플리케이션의 컴포넌트를 렌더링하는 과정이 조금 달라진다. 기존의 ReactDOM.render()는 한 번 호출되면 해당 컨테이너에 대한 렌더링이 완료될 때까지 다시 호출할 수 없다. 하지만 createRoot() 함수를 사용하면 여러 번 호출하여 동일한 루트 요소에 여러 개의 리액트 애플리케이션을 렌더링할 수 있다.