에어비앤비 클론코딩

에어비앤비 클론코딩(6) - Virtual DOM

망또또의 언냐 2022. 9. 7. 19:51

Virtual DOM 란? Virtual DOM이 무엇인지 그리고 기존 웹이 사용하는 DOM과의 차이점

 

DOM

DOM은 HTML과 자바스크립트를 이어주는 공간으로, 내가 작성한 HTML을 자바스크립트가 이해할 수 있도록 객체(object)로 변환하는 것이다.

 

DOM은 내가 작성한 HTML로 부터 생성되지만, 브라우저가 알아서 필요한 노드들을 붙여준다. 예를 들어, <head>나 <body>없이 <html>안에 어떠한 내용을 작성을 하더라도, 브라우저로 열어보면 자동으로 생성되어 있다. 그리고 자바스크립트로 인해 새로운 노드를 추가할 수도 있다.

 

const newTextDiv = document.createElement('div')
const helloWorld = document.createTextNode('Hello world!')
newTextDiv.appendChild(helloWorld)
document.body.appendChild(newTextDiv)

 

따라서, 자바스크립트를 DOM API라고 부르기도 한다.

DOM은 오타 수정, 문구 제거 혹은 이미지를 첨부하는 사소한 일을 하더라도, DOM은 처음부터 다시 HTML을 파싱하여 DOM 트리를 만들고 CSS를 파싱하여 Render 트리를 만들고, 레이아웃을 입혀 출력한다.

 

2000년도 초만 하더라도 하나의 웹 사이트에 몇 페이지 없었을 테지만, 현재 대부분의 웹 사이트는 수 십개 심지어 수 백, 수 천개의 페이지로 이루어졌다. 겨우 오타 하나를 잡고 싶을 뿐인데, 전체 사이트를 다시 처음부터 렌더링(위의 결과물 출력 과정)을 해야 하며, 해당 오타를 찾기 까지 너무나 많은 시간이 들어가 상당히 비효율적이다.

 

그래서 Virtual Dom이 나왔다.

Virtual Dom

Virtual Dom(이하 가상 DOM)은 수정사항이 여러 가지 있더라도, 가상 DOM은 한 번만 렌더링을 일으킨다.

 

 

위의 그림처럼, 가상 DOM은 DOM이 생성되기 전, 이전 상태 값과 수정사항을 비교하여 달라진 부분만 DOM에게 한 번에 전달하여 딱 한 번만 렌더링을 진행한다.

 

수정사항이 생겼다면, 가상 DOM이 알아서 달라진 값을 탐지하여 변경하고 최종적인 결과물을 실제 DOM에 전달한다. 만약 가상 DOM이 없었다면, DOM은 렌더링을 처음부터 해야했다.

“직접 DOM에 접근하는 것은 지양해야 한다.”

이는 DOM에 직접 접근해도 문제가 되진 않지만, DOM이 직접 변경된다면 사소한 변경사항에도 전체가 재렌더링 되기 때문에 브라우저에 과부하가 올 수 있다. 따라서 최대한 DOM에 직접 접근하지 말아야 한다, 라고 이해하면 될 것 같다.

 

https://www.howdy-mj.me/dom/what-is-dom/

 

 


클래스형 컴포넌트 vs 함수형 컴포넌트

 

 과거에는 클래스형 컴포넌트를 주로 사용했지만, 2019년 v16.8 부터 함수형 컴포넌트에 리액트 훅(hook)을 지원해 주어서 현재는 공식 문서에서 함수형 컴포넌트와 훅을 함께 사용할 것을 권장하고 있다.

 

클래스형 컴포넌트와 함수형 컴포넌트의 역할은 동일하다. 차이점이 있다면 클래스형 컴포넌트의 경우 state 기능 및 라이프 사이클 기능을 사용할 수 있으며 임의 메서드를 정의할 수 있다는 점이다. 그리고 render 함수가 꼭 있어야 하고, 그 안에서 보여 주어야 할 JSX를 반환해야 한다. 또한 과거의 prototype을 이용해서 구현하던 클래스 문법을 ES6 문법 부터는 class 문법을 사용하여 구현할 수도 있다.

 

반면 함수형 컴포넌트는 클래스형 컴포넌트보다 선언하기가 좀 더 편하고, 메모리 자원을 덜 사용한다는 장점이 있다. 과거에는 함수형 컴포넌트에서 state와 라이프사이클 API를 사용할 수 없다는 단점이 있었는데, 이러한 단점은 앞서 언급한 것처럼 리액트 훅이 도입되면서 해결되었다. 

 


 

첫번째 차이 : 선언방식

 

클래스형 컴포넌트

class 키워드가 필요하다.

component로 상속을 받아야 한다.

render() 메소드가 반드시 필요하다.

state, lifeCycle 관련 기능사용이 가능하다.

함수형보다 메모리 지원을 더 사용한다.

임의 메소드를 정의한다.

 

state, lifeCycle 관련 기능 사용이 불가능하다.(Hook을 통해 해결할 수 있다.)

클래스형보다 메모리 자원을 덜 사용한다.

컴포넌트 선언이 편하다.

 

 

 

※ es6 화살표 함수와 일반 function() 함수의 차이 :

일반 함수(function())는 자신이 종속된 객체를 this로 가리키며, 화살표 함수(() => {})는 자신이 종속된 인스턴스를 가리킨다.

 

 

두번째 차이 : state

 

State 란?

컴포넌트 내부에서 바뀔 수 있는 값

 

<클래스형 컴포넌트>

1. constructor 안에서 this.state 초기 값 설정 가능

2. counstructor 없이도 바로 state 초기값을 설정 가능

3. this.setState() 를 통해 state값을 변경

4. 클래스형의 state는 객체형식

 

<함수형 컴포넌트>

1. useState 함수로 state를 사용한다.

2. useState 함수를 호출하면 배열이 반환되는데 첫 번째 원소는 현재 상태, 두번째 원소는 상태를 바꿔주는 함수이다.

 

 

세번째 차이 : props

 

Props 란?

- 컴포넌트의 속성을 설정

- 읽기 전용 (컴포넌트 자체 props를 수정하면 안된다.)

- 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야한다.

- 수정되는 값은 state 이다.

 

<클래스형 컴포넌트>

1. this.props로 통해 값을 불러올 수 있다.

 

<함수형 컴포넌트>

1. props를 불러올 필요 없이 바로 호출 할 수 있다.

 

 

네번째 차이 : 이벤트 핸들링

 

<클래스형 컴포넌트>

1. 함수 선언시 화살표 함수로 바로 선언 가능하다.

2. 요소에 적용할때 this.를 붙여줘야한다.

 

<함수형 컴포넌트>

1. const + 함수 형태로 선언해야 한다.

2. 요소에 적용할때 this가 필요없다.

 

 

 

 

https://born-dev.tistory.com/27

https://devowen.com/298