Land of Joe

23년 12월 28일 심화과정#3 Virtual DOM, Hook, State.. 본문

🌱 dailyStep/⏳ StageUs

23년 12월 28일 심화과정#3 Virtual DOM, Hook, State..

Arendt 2023. 12. 30. 17:11

 

드디어 마르고 닳도록 들어본 (듣기만 한) 개념들에 대해 배웠다.

아직 리액트 어플(CRA..뭔지 잘 모름)에 한 건 아니고, 그냥 html에 바벨 라이브러리 설치해서 script 안에 개발하고 있다.

 

CRA를 사용하지 않은 바벨의 특성 상(?) html 파일 하나에 전부 때려박아야 해서

파일을 컴포넌트 단위로 나누어보지도 않아

아직 내가 리액트를 하고 있다는 게 별로 실감이 나지 않았는데 

그동안 유튜브 등에서 귀동냥으로 들어왔던 리액트 대표 개념들을 배우니 뭔가 설레었따. 히히

 

여튼 시좍좍

 


 

1. Virtual DOM 버츄얼 돔

 

1-1. Virtual DOM의 존재 이유

  • 요즘같이 한 페이지에 많은 데이터를 출력하는 웹에 있어 브라우저의 동작 구조는 매우 비효율적이다.
[ 브라우저 동작 구조 ]

(1) DOM Tree 생성: html을 분석해서 DOM 구조를 RAM에 저장함
(2) Render Tree 생성: (1)에서 만든 DOM Tree에 외부 CSS를 붙임
(3) Reflow: (2)를 기반으로, 모니터 사이즈를 고려해서 실제 물리적 좌표를 계산함
(4) Painting: (3)에서 구한 물리적 좌표에 따라 실제 화면에 그려줌
  • 브라우저가 효율적이지 못한 이유: 이벤트 등으로 화면에 변화가 일어나면 브라우저 랜더링 과정을 다시 진행한다. (페이지 자체를 새로고침, 세 개의 이벤트가 발생하면 브라우저 랜더링을 세 번 진행함)

컴포넌트 단위로 랜더링이 가능하게 하는 원리가 바로 virtual DOM이다 !

 

1-2. Virtual DOM의 동작구조

  • 기존 브라우저 랜더링 방식에 맨 앞에 한 단계를 더 추가한다. ('Virtual Tree'라는 가칭을 붙여본다)
  • 이벤트가 발생해서 DOM에 변화가 생겼을 때 먼저 Virtual Tree에 반영한다. (브라우저에 바로 보이지 않는다)
  • 현재 브라우저의 화면과 Virtual Tree 사이의 차이점을 계산할 수 있다.
  • 실질적으로 변경된 부분만을 브라우저에 전달한다.
[ Virtual DOM의 동작구조 ]

< ------ 이벤트 발생 ------- >
(0) (Virtual Tree) 생성: 이곳에 먼저 반영하고, Virtual DOM을 통해 현재 브라우저 화면과의 차이점을 계산함
(1) DOM Tree 생성: 계산된 차이점만의 html을 분석해서 DOM 구조를 RAM에 저장함
(2) Render Tree 생성: (1)에서 만든 DOM Tree에 외부 CSS를 붙임
(3) Reflow: (2)를 기반으로, 모니터 사이즈를 고려해서 실제 물리적 좌표를 계산함
(4) Painting: (3)에서 구한 물리적 좌표에 따라 실제 화면에 그려줌

 

1-3. Virtual DOM의 장점

  • 여러 번 반복되는 브라우저 랜더링 과정을 한 번에 몰아서 처리하게 되었다.
  • 변화된 부분만을 전달하는 것을 통해, 페이지 단위가 아닌 컴포넌트 단위로 새로고침이 가능하게 되었다. 

but, 무조건 이로운가? NO!

 

1-4. Virtual DOM의 단점

  • 브라우저의 동작 구조가 한 스텝 더 늘어났..다...
  • 가상의 Tree라는 것 자체가 RAM을 더 잡아먹는다.
  • so, 만약 내가 만들 프로젝트에 컴포넌트 단위의 랜더링이 없다면 오히려 손해인 것임..
  • 개발자가 리액트를 잘못 사용해 컴포넌트 설계를 잘못하면 이벤트를 발생시켰을 때 컴포넌트 단위가 아닌, 페이지 단위가 새로고침되게 개발될 수도 있다....

Virtual DOM을 개발자가 사용하는 방법이 바로 State다!

버츄얼 돔과 연계해서 State를 이용하는 이유를 이해해야 한다!!!!!!!!

 

 

한 줄 정리:

바닐라 웹 페이지 단위의 새로고침을 개선하고자
Virtual DOM 원리를 이용한 
컴포넌트 단위의 새로고침을 가능하게 하였다.

 

 


 

2. Hook

 

2-1. Hook의 정의

  • 기존 JS에서는 중복되는 로직 코드를 분리시키기 위해 모듈(aka. 함수)을 만들어왔다.
  • Hook이란 리액트에서 사용하는 모듈을 의미한다. 
  • JS 모듈에서는 리액트 문법을 사용할 수 없는 반면,
  • Hook에서는 리액트 문법을 사용할 수가 있다. (그냥 리액트 전용 함수라고 보면 됨)

 

2-2. Hook의 종류

(1) 리액트 내장 훅

  • 리액트가 만들어둔 모듈 함수
  • useState, useEffect, useRef, useMemo, useCallback 등….
  • 리액트를 고급지게 다루기 위해 알아야 하는 모듈 함수라고 보면 된다. 

- useState : state를 만들고 업데이트하기 위한 모듈

- useEffect : 컴포넌트가 랜더링된 직후 뭔가를 해야할 때, 이를 처리하게 하는 모듈

- useRef: 컴포넌트를 변수에 임시로 저장하게 하는 모듈 (getElementById와 유사)

 

(2) Custom Hook

  • 사용자가 직접 만든 리액트 전용 함수
  • 만드는 데 규칙이 존재한다.

규칙1) Custom Hook을 만들 때는 꼭 함수의 이름이 'use'로 시작해야 한다.

규칙2) 모든 커스텀 훅은 리액트 함수를 통해서만 호출해야 한다. (자바스크립트 모듈을 통해서는 안 됨)

 

 

 

✔︎ 최종 한 줄 정리: 

 

 

바닐라 웹 페이지 단위의 새로고침을 개선하고자
Virtual DOM 원리 작동시키는 HOOK을 이용해 개발하여
컴포넌트 단위의 새로고침을 가능하게 하였다.

 



✔︎ 리액트 개발하면서 유의해야 할 점: 

어떻게 함수를 설계하고 어떻게 컴포넌트를 설계할 것인지 계속해서 고민하기!



3. State

3-1. State의 정의

- 변수의 한 종류 (Component Library에만 존재하는 개념)

- Virtual DOM을 동작시키는 트리거 역할

- Virtual DOM은 사실 State를 감시하고 있는 역할이다.
감시하고 있는 State에 변화가 있으면, 그 State를 사용하고 있는 컴포넌트만 새로고침시키는 원리인 것!!

 

3-2. 기존 개발 방식과의 비교

- 기존 개발 방식에서 이벤트를 통해 페이지를 변화시키는 건 오직 개발자의 몫이었다.

(이벤트를 통해 개발자가 코드를 작성해 태그를 불러오고, 그 태그에 값을 바꿔주거나, CSS를 직접 바꿔주는 방식)

- 더이상 개발자가 이벤트 내에서 태그에 변화되는 점을 직접 써주지 않는다!!!!!

-> 이벤트 안에서 오직 State를 업데이트하기 하게 되었다!

-> 그럼 이제 나머지는 Virtual DOM이 알아서 하게 되었다.

-> return 부분에 이벤트 진행 시 어떤 식으로 돌아갈지 미리 적어준다. ⇒ 이벤트 내용이 훨씬 깔끔해진다.


Q. 그럼 무조건 State만 써야겠네? 변수는 그럼 이제부터 안 쓰는가??

A. 원래 변수의 목적대로 임시로 값을 담아주는 역할만 할 때에는 State를 쓰는 게 오히려 손해
(Virtual DOM이 감시할 대상을 늘리는 거니까)


즉, 

State: 이벤트를 통해 화면에 변화가 일어나야 하는 값

Variable: 임시로 저장되어야 하거나, 변화가 없는 값들

3-1. State의 사용 예시

- 전역변수나 설정 값의 느낌으로 사용되는 값 (nav 열기/닫기 이벤트)

- 직접적으로 화면에 출력되는 값인데, 이벤트에 따라 값이 바뀌는 것

- 백엔드에서 오는 데이터는 거의 100% State로 처리


4. Re-Rendering

4-1. Re-Rendering정의

- 새로고침을 의미

- 앞으로 컴포넌트 설계할 때 추가로 고려해야하는 대상임 (State에 의한 컴포넌트 설계)

 

4-2. Re-Rendering이 일어나는 경우

- State가 변경됐을 때

- 부모에서부터 온 props가 변경됐을 때

- 부모 컴포넌트가 리랜더링 됐을 때 자식 컴포넌트는 무조건적으로 리랜더링 된다.

Q. 만약 모든 State를 App()에 선언하면 어떤 일이 벌어질까?

A. 페이지 전체가 리랜더링 된다. -> 컴포넌트 설계를 잘못했을 때 바닐라웹을 사용하는 것보다 성능이 낮을 수도 있음…! 최악......ㅠ


** 컴포넌트 설계 원칙 최종 정리

 

1. 재활용성 고려 (map)

2. 데이터 선언 지점 분리 (백엔드 통신과 밀접한 관련)

3. 너무 길 때 의미적으로 분리

4. State를 고려해서 이벤트의 시작지점과 도착지점을 묶어줄 것

(별도로 분리를 시킬 수도 있고, 따로 컴포넌트를 만들어서 묶어줄 수도 있음)

** State의 변화는 무조건 이벤트 혹은 Hook을 이용해야만 한다. 그렇지 않고 State 업데이트 코드를 넣게 되면 무한 리랜더링 오류가 발생하게 된다. set함수를 통해 State 업데이트를 하면 컴포넌트가 리랜더링 되기 때문이다. 유의할 것. 


++추가
컴포넌트 설계 원칙 4번-이벤트의 시작지점과 도착지점을 묶어주는 개념-에 대해
과제를 하면서 얻은 사례로 이해를 탄탄히 하고자 한다. 






수업 시작 전엔 설레었는데

수업이 진행될수록 그 마음에 사막화가 진행되었다.ㅋ

뭔가 알 듯 말 듯 알쏭달쏭하다. 근데 생각해보면 난 항상 매번 수업마다, 아니 인생 전체가 그랬던 것 같다.

뭐 하나를 배우면 그 자리에서 바로 명쾌하게 내 것이 된 적은 한 번도 없다. 

그러나 복습을 하고 과제를 하다보면 어느 순간 내 것이 되어있었다. 무조건. 

이게 나를 공부에 자신감을 갖게 만든 과정이었다.

 

개발공부에 한해선 그런 자신감(언젠간 무조건 내 것이 될 거라는)이 부족했는데

어느새 또 내 마음 속에 자리 잡은 것 같다고 오늘 수업이 끝나갈 무렵 생각이 들었다.

굳이 따져본다면 모의외주가 끝나갈 무렵부터였던 것 같다.

지금 당장은 알쏭달쏭하더라도 뭐, 하다보면 어떻게든 되겠지, 내가 어떻게든 해내겠지~ 이런 마음..!

 

그러고보니 올해의 마지막 수업이었다.

수업 차수를 세어보니 이제 막 반을 넘었더라.

반 오기까지 눈물, 밤샘, 외로움이라는 산들이 산맥을 이루고 나를 감싸 고립시키는 기분이었는데..

이제야 반이라니 싶은 마음도 들고,

앞으로의 반은 조금 자신 있는 자세로 당차게 해나갈 수 있으려나..? 싶은 궁금하고도 기대되는 마음이다.

 

 

역시 나는 개발 공부 기록보단 내 마음을 살펴보는 수필이 더 좋다. 헤헤

이런 글을 쓰면 마음이 정리되어 정화된 듯한 맑은 기분이 든다.

 

여튼 끄읏~