지난 포스팅인 코딩하는데 4시간, 배포하는데 1시간 걸렸던 [첫 배포하기] 이후에 리액트를 학습하게 되었다.

파트 2에서 같은 팀에 배정 된 분들이 노션을 많이 사용하셨는데 쓰다보니 마크다운 언어에 흥미를 느껴 노션을 즐겨 사용하게 되었다. 덕분에 블로그에 조금 뜸하게 들어왔지만,.. 역시 회고는 블로그가 제 맛이다.

팀 프로젝트에서 나의 역할은 공통영역, 헤더, 버튼, 카드 (컴포넌트) 이다.

코린이와 첫 프로젝트 진행으로 많은 난관이 예상되는 나는 팀원분들의 배려로 그나마 쉬운(?, 근데 사실 쉽지 않다는 멘토님의 말씀🥲🫠) 부분을 맡게 되었는데 하,, 쉽지 않다. 뭐랄까 신경써서 해야할게 너무 많다. 규칙은 뭐가 그렇게 많고 복잡한지 모르겠다.🥲 울고싶지만 어쩌겠는가. 해내야지.

사용하기로 한 기술

  • React, Vite, react-router
  • Prettier, ESLint, Husky
  • Tailwind CSS
  • VSCode, Figma, Github

라이브러리

  • 에디터
  • /list 페이지 캐러셀
  • 이모지 기능
  • axios

코드 컨벤션, 네이밍 컨벤션, 커밋 메시지 컨벤션

    • 코드 컨벤션 : 토스트 컨벤션 (너무 세세하진 않게)
      • 코딩 컨벤션은 읽고, 관리하기 쉬운 코드를 작성하기 위한 일종의 코딩 스타일 규약
      • 들여쓰기 : space와 tab을 섞어서 사용하지 않기.
      • 문장의 종료 : 한줄에 하나의 문장만 허용! 문장 종료시 세미콜론(;) 사용!
      • 명명규칙 : (기본, 변수나 함수) 카멜 케이스 사용, 예약어 사용X, 상수는대문자 SNAKE_CASE 사용
      • 전역변수 사용 X
      • 값이 변하지 않는 변수는 const 변하는 변수는 let 사용 (var 사용금지)
      • const를 let보다 위에 사용하고 선언시점에 선언 및 할당 할 것
      • 배열과 객체는 반드시 리터럴로 선언
      • 일관된 줄바꿈
      • 주석은 설명하려는 구문에 맞춰 들여쓰기 
    • 네이밍 컨벤션 : 브랜치 작업 시 모아서 정하기
    • 커밋 메시지 :
      • feat : 새로운 기능 추가
      • fix : 버그 수정
      • docs : 문서의 수정
      • style : (코드의 수정 없이) 스타일만 변경 (들여쓰기 같은 포맷이나 세미콜론을 빼먹은 경우 등)
      • design : 사용자 UI 디자인 변경 (CSS 등)
      • refactor : 코드를 리펙토링
      • test : TEST 관련한 코드의 추가, 수정
      • chore : (코드의 수정 없이) 설정을 변경, 
      • build : 빌드 파일 수정
      • ci : CI 설정 파일 수정
      • perf : 성능개선
      • rename : 파일 혹은 폴더명을 수정만 할 경우
      • remove : 파일을 삭제만 한 경우 

커밋 메시지의 7가지 규칙

        1. 제목과 본문을 빈 행으로 구분한다.
        2. 제목은 50글자 이내로 제한한다.
        3. 제목의 첫 글자는 대문자로 작성한다.
        4. 제목 끝에는 마침표를 넣지 않는다.
        5. 제목은 명령문으로 사용하며 과거형을 사용하지 않는다.
        6. 본문의 각 행은 72글자 내로 제한한다.
        7. 어떻게 보다는 무엇과 왜를 설명한다.
          • Header는 필수이며 스코프는 생략 가능
          • 타입은 해당 커밋의 성격을 나타내며 위 타입 중 하나여야 한다.
          • Body는 Header에서 표현할 수 없는 상세한 내용을 적는다.
          • Footer는 바닥글로 어떤 이슈에서 왔는지 같은 참조 정보들을 추가하는 용도로 사용
          • Footer는 생략 가능
          • 예를 들어 특정 이슈를 참조하려면 Issues #1234 와 같이 작성
          • Header에서 충분히 표현할 수 있다면 생략 가능
// Header, Body, Footer는 빈 행으로 구분한다.
타입(스코프): 주제(제목) // Header(헤더)

본문 // Body(바디)

바닥글 // Footer
git commit -m "fix: Safari에서 모달을 띄웠을 때 스크롤 이슈 수정

모바일 사파리에서 Carousel 모달을 띄웠을 때,
모달 밖의 상하 스크롤이 움직이는 이슈 수정.

resolves: #1137

폴더 구조

프로젝트폴더/
├── node_modules/     # 설치된 패키지들
├── public/          # 정적 파일들
│   ├── vite.svg
├── src/
│   ├── components/  
│   │   ├── Button/
│   │   │   ├── index.jsx
│   │   │   └── styles.js
│   │   ├── Card/
│   │   │   ├── index.jsx
│   │   │   └── styles.js
│   │   ├── Header/
│   │   │   ├── index.jsx
│   │   │   └── styles.js
│   │   └── Footer/
│   │       ├── index.jsx
│   │       └── styles.js
│   ├── pages/
│   │   ├── Home/
│   │   │   ├── index.jsx
│   │   │   └── styles.js
│   │   ├── About/
│   │   │   ├── index.jsx
│   │   │   └── styles.js
│   ├── api/               
│   │   ├── axios.js       # axios 인스턴스 및 인터셉터 설정
│   │   ├── auth.js        # 인증 관련 API
│   │   └── product.js     # 상품 관련 API
│   ├── routes/            # 라우팅 관련 폴더 추가
│   │   ├── Router.jsx     # 라우터 설정
│   ├── styles/
│   │   ├── GlobalStyle.js
│   │   └── theme.js
│   ├── assets/
│   │   └── images/
│   │       ├── logo.png
│   │       └── banner.jpg
│   ├── App.jsx
│   └── main.jsx
├── .gitignore       # Git 제외 파일 설정
├── .env.local       # 로컬 환경 변수 (git에서 제외됨)
├── .eslintrc.js    # ESLint 설정
├── .prettierrc     # Prettier 설정
├── package.json    # 프로젝트 설정 및 의존성
├── package-lock.json  # 의존성 버전 고정
├── README.md       # 프로젝트 문서
└── vite.config.js  # Vite 설정 (CRA의 경우 불필요)

브랜치 전략

  • Git Flow 전략
    • 예시_ feat/from, feat/components
    • main 브랜치 :  제품 출시 버전을 관리하는 메인 브랜치 . 프로젝트 시작시 생성된다. 개발 프로세스 전반에 걸쳐 유지
    • develop 브랜치 : 다음 버전 개발을 위한 코드를 모아두는 브랜치. 개발완료 후 main 브랜치로 머지됨
    • feature 브랜치 : 하나의(새로운) 기능을 개발하기 위한 브랜치. develop 브랜치에서 생성. 기능이 개발 완료 되면 develop 브랜치로 머지.
      • 주의할 점 : Fast-Forward로 머지하지 않고 Merge Commit 을 생성하며 머지를 해주어야 함
      • 그래야 히스토리가 특정 단위로 묶임
      • 네이밍은 조금씩 차이가 있지만 "feature/branch-name"과 같은 형태로 생성
    • release 브랜치 : 소프트웨어 배포를 준비()하기 위한 브랜치. develop 브랜치에서 생성. 버전 이름 등의 소소한 데이터를 수정하거나 배포 전 사소한 버그 수정. 배포 준비 완료 후 main과 develop 브랜치에 둘다 머지. 이 때 main  브랜치에는 태그를 사용하여 버전 표시
      • 네이밍은 "release/v1.1"과 같은 형태로 생성
    • hotfix 브랜치 : 이미 배포된 버전에 문제 발생 시 이 브랜치를 통해 문제 해결. main 브랜치에서 생성. 문제 해결 완료 되면 main과 develop 브랜치에 둘 다 머지
      • 네이밍은 "hotfix/v1.0.1"과 같은 형태로 생성
  1. 신규 기능 개발을 위해 개발자는 develop 브랜치를 기준으로 한 feature 브랜치를 따서 작업을 진행.
  2. 작업이 완료된 feature 브랜치는 develop 브랜치로 병합 (Merge) 된다. (일반적으로 프로젝트 진행 시에는 Pull Request 를 통해 작업 내용을 Review 받은 후 해당 PR 을 Merge 하는 방식으로 진행한다고 함.)
  3. 다음 출시 버전을 위해 개발 중인 develop 브랜치에서 release 브랜치를 따서 배포를 위한 준비. (이 때 발견되는 버그들은 release 브랜치에서 바로 반영.)
  4. 충분한 테스트 후에, 일정한 주기로 (일반적으로는 배포하고자 하는 버전 단위) main 브랜치로 Merge 하여 제품을 출시.
  5. 상용 배포 이후, release 브랜치에서 미처 발견되지 못한 새로운 버그들은 hotfix 브랜치에 바로 반영.

1단계 Github 팀 계정 fork 하기

가장 먼저! 프로젝트를 위해 팀장님이 만들고 초대해주신 Github 프로젝트를 팀원들은 각자 개인 Github 레포지토리로 fork 해야한다.

복습하는 느낌으로 다시 해보도록 하자. 먼저 Fork 해주기.

더보기

💡Fork 해주는 이유? 다른 사람의 GitHub 저장소를 내 계정의 Github로 복사해오기 위해서!

✔️fork 후에는 원본 repository의 변경 사항을 내 repository에 반영하거나, 내 repository의 변경 사항을 원본 repository에 반영하도록 요청할 수 있다.

그리고 나서 나오는 이 화면에서 중요한 Tip! 

현재 Copy the main branch only의 체크박스에 체크가 되어있는데 이 뜻은 fork(복사)해 오는데 main 브랜치만 가져올건지 묻는것이다. 나는 팀프로젝트를 진행할거고 다른 브랜치에서 작업을 해줘야 하기 때문에 (이미 만들어져 있고 내가 만들게 아니기도 함) 꼭 체크박스를 해제 해주고 create fork를 해주도록 하자.

2단계 clone하기

그 다음으로 fork 해온 내 레포지토리를 로컬 작업 환경으로 clone해야한다.

더보기

💡clone이란? github 레포지토리의 코드를 내 컴퓨터(로컬)로 가져오는 것

내 Github 레포지토리에서 fork 된 주소 확인(복사)하기!
VS Code 열어 터미널 창에서 명령어 입력하기!

git clone {fork 해 온 나의 repository 주소}

쨔쟌, 현재 디렉토리 아래에 프로젝트 이름을 따서 디렉토리를 만들고, 그 아래에 저장소를 복사한다. 여기서는 프로젝트 이름은 rolling이다.

만들어진 rolling 디렉토리

3단계 원본 레포지토리 연결하기

clone으로 가져오면 기본적으로 origin이라는 이름에 내 원격저장소 URL이 연결된다.

원본 레포지토리 주소를 연결해줘야 내 컴퓨터(로컬)로 원본 레포지토리의 변경사항을 반영시킬 수 있기 때문에 연결을 해주어야 한다.

# 원격저장소 remote등록
git remote add {이름} {저장소 URL}

# 예시_ 원본 github 레포지토리를 upstream 이라는 이름으로 연결.
# git remote add로 연결한 후에는 추후에 다시 연결하지 않아도 된다.
git remote add upstream https://github.com/예시URL주소/rolling.git

# 원격저장소 확인
git remote -v

보통은 내 원격 저장소의 이름을 origin으로, 원본 저장소의 이름을 upstream으로 하는 것 같다.

remote 하기 전과 후의 원격 저장소 차이

4단계 브랜치 만들고 나누기

협업에서 정말 중요한 필수! 브랜치를 나눠놔야 어떤 브랜치에서 작업하던게 문제가 생기더라도 main에서의 코드는 유지되어 있기 때문에 role back(이전 리비전으로 문서를 되돌리는 행위)하기 쉽다.

우리 팀은 브랜치 전략으로 Git flow 전략을 쓰기로 해서 일단 develop 브랜치를 따로 만들어야한다.

# 브랜치 생성 명령어
git branch {브랜치명}

# git branch {생성할 브랜치명} {기준 브랜치명}
git branch develop main

# 브랜치를 잘못 만들었을 때 브랜치명을 수정할 수 있는 방법
git branch -m {잘못 만든 브랜치명} {수정할 브랜치명}

# 브랜치 이동
git checkout {브랜치명}

# 생성과 동시에 이동하는 옵션
git checkout -b {브랜치명}
 
# 브랜치 리스트 확인
git branch

Git Flow 구조 예시

master (또는 main)  # 실제 서비스 중인 코드
  └── develop       # 개발 중인 코드
      └── feature/login
      └── feature/payment
  └── hotfix        # 긴급 버그 수정
  └── release       # 출시 준비

5단계 만든 브랜치에서 작업 후 해야하는 것

브랜치를 만들고 개인 브랜치에서 코드 작업을 한다. 

코드 작업을 마친 후 코드를 저장한다.

# 현재 폴더의 변경 사항을 저장하기 위해 모두 '지정'한다.
git add .

# 지정한 파일들을 git에 저장한다.
git commit -m "메세지 입력"

그리고 본인 Github 레포지토리에 업로드 한다.

git push origin <브랜치명>

# 예시
git push origin Basic-step

💡여기서 주의해야할 것, push를 upstream(원본 저장소)에 하지 말고 origin(나의 원격 저장소)에 해야한다.

6단계 PR 요청

push까지 마치고 나면 내 Github저장소 compare & pull request 버튼이 생성되어 있다. 해당 버튼을 눌러서 전달사항 및 변경사항을 기록하고 pull request 요청하면 된다.

Pull Request란 '코드를 수정했는데 당신도 코드를 수정했다면 제 수정한 내용도 적용시켜 주세요' 라는 의미이다.


작업을 하다보면 PR을 이미 했는데 '아! 이거도 같이 수정(추가)해서 할걸!'할 때가 있다.
이럴 땐 굳이 PR을 취소하고 다시 commit/push후 PR할 필요 없이 그냥 PR이 이미 올려진 상태에서 commit/push를 진행하면 된다. (같은 branch로 push 해야함.)

그러면 해당 branch에 대한 PR에 추가로 push한 commit기록이 쌓이게 된다.

다만 협업의 경우 내가 추가 push하기 전에 다른 사람이 PR확인 후 merge시킬 수 있으니 미리 고지 후에 추가로 push하는 것이 좋다.

7단계 머지(merge)

작업한 내용을 PR요청하면 다른 팀원은 원본 저장소에서 PR 내용을 확인 할 수 있다.

그리고 해당 내용이 다른 코드에 영향을 미치지 않고, 원본 저장소에 반영해도 되겠다는 판단이 들면 그때 하는 것이 merge. 즉, 변경사항을 원본에 병합하는 것이라고 생각하면 된다.

만약 merge를 진행하게되면 PR내용은 닫혀서 사라지게 되고 원본 저장소에는 바뀐 내용이 반영되어 합쳐진다.
(문제가 있다고 판단될 시에는 이를 거절할 수도 있다.)

# 1. 메인 브랜치로 이동
git checkout main

# 2. 기능 브랜치 병합
git merge feature/login

## 실제예시 상황
# 1. 로그인 기능 완성 후 메인으로 이동
git checkout main

# 2. 로그인 브랜치 병합
git merge feature/login

# 3. 기능 브랜치 삭제 (선택사항)
git branch -d feature/login

8단계 merge가 완료되면

merge가 완료되면 내 로컬 파일에도 다른 사람이 추가한 내용이 반영된다.

#git pull {원본 remote 이름} {브랜치명}

git pull upstream develop

9단계 브랜치 삭제

해당 작업이 완료된 branch는 삭제해준다.

git branch -d {브랜치명}
  1. 배열 안에는 여러 개의 요소가 있을 수 있다. 이 요소들각기 다른 key 값을 가지면, 리액트는 각 요소를 고유하게 식별할 수 있다. 이는 마치 친구들의 이름처럼 각 요소를 구분하는 역할을 한다.
  2. 리액트는 배열의 요소가 바뀔 때, 어떤 요소가 추가되거나 삭제되었는지를 알아야 한다. key가 있으면 리액트는 변화가 생긴 부분만 빠르게 업데이트할 수 있는데 이는 성능을 향상시키고 불필요한 렌더링을 줄여준다.
  3. 만약 배열의 요소가 이전과 같은 key를 가지고 있다면, 리액트는 그 요소의 상태(입력값, 클릭 상태 등)를 유지할 수 있다. 반면 key가 없거나 중복된다면, 상태가 잘못될 수 있다.
  4. key가 없으면 리액트는 어떤 요소어떤 것인지 헷갈릴 수 있다. 이로 인해 렌더링 결과가 이상해질 수 있는데 각 요소정확하게 식별하기 위해서는 key가 필요하다.
//key가 없다면 리액트는 어떤 요소가 어떤 상태를 가지고 있었는지를 알기 어렵다.
[
  { id: 1, text: '사과', isChecked: false },
  { id: 1, text: '바나나', isChecked: false } // 중복된 key
]
//만약 사용자가 첫 번째 항목(사과)의 체크박스를 클릭하면, 
//리액트는 두 항목이 동일한 key를 가지고 있기 때문에 두 항목 모두 체크된 것으로 잘못 인식할 수 있다.

💡배열이 아니라 노드 / 컴포넌트에 key 값을 부여한다고 이해해도 괜찮다. 리액트 뿐만 아니라 뷰 등 대부분 프레임워크에서 key 값을 사용한다.

'코린이 개념잡기 > React' 카테고리의 다른 글

리액트가 뭐에요?  (0) 2025.01.09
브라우저가 리액트를 알아듣는 원리  (0) 2025.01.04
리액트 렌더링  (0) 2025.01.03
리액트 디자인 적용하는 방법 +🍯  (4) 2025.01.03
State  (3) 2025.01.03
  • 리액트자바스크립트 라이브러리로 사용자 인터페이스(User Inerface 줄여서 UI)를 구축하기 위해 사용한다.
  • 리액트컴포넌트 기반으로 설계되어 있어 재사용성 유지보수성이 높다. 리액트를 사용하면 복잡한 UI를 쉽게 관리하고 업데이트할 수 있다.
라이브러리(Library)?

-라이브러리는 특정 기능이나 작업을 수행하기 위해 미리 작성된 코드의 집합
-프로그래밍에서 라이브러리를 사용하면 반복적으로 작성해야 하는 코드를 줄이고, 개발 시간을 단축할 수 있다.

리액트에서 특정 부분이 어떻게 생길지 정하는 선언체를 컴포넌트(Component)라고 한다.

컴포넌트(Component)?

컴포넌트는 리액트에서 UI를 구성하는 기본 단위이다. 각각의 컴포넌트는 독립적으로 동작하며, UI의 특정 부분을 나타낸다. 예를 들어, 버튼, 입력창, 아이템 등과 같은 요소들이 각각의 컴포넌트로 구현될 수 있다.

1. 재사용성: 한 번 작성한 컴포넌트를 여러 곳에서 재사용할 수 있다.

2. 독립성: 각 컴포넌트는 자신의 상태(state)와 속성(props)을 가질 수 있어, 서로 독립적으로 동작한다.
3. 구조화: 복잡한 UI를 작은 단위로 나누어 관리할 수 있어, 코드의 가독성과 유지보수성을 높인다.

컴포넌트는 다른 프레임워크에서 UI를 다룰 때 사용하는 템플릿과는 조금 다르다. 템플릿은 보통 데이터셋이 주어지면 HTML 태그 형식을 문자열로 반환하는데, 컴포넌트는 좀 더 복합접인 개념이다. 재사용이 가능한 API로 수 많은 기능들을 내장하고 있으며, 컴포넌트 하나에 해당 컴포넌트의 생김새와 작동 방식을 정의한다.

API (Application Programming Interface)

  •  소프트웨어 간의 상호작용을 가능하게 하는 일종의 인터페이스
  • 다른 프로그램이나 서비스와 데이터를 주고받거나 기능을 사용할 수 있도록 해주는 규칙이나 프로토콜

클라이언트가 요청을 보내고 서버가 응답하여 클라이언트로 보내면, 클라이언트는 화면에서 서버가 응답한 답을 볼 수 있는데 "클라이언트가 A라는 요청을 보내면 B라는 응답 값을 주세요."라고 약속한 내용을 API라고 할 수 있다.

클라이언트 (정보요청) → API → (정보요청) 서버 ❘❘ 클라이언트 (데이터 전달) ← API ← (데이터 전달) 서버

렌더링(rendering)

웹 페이지나 앱에서 화면에 내용을 보여주는 과정을 말한다. 쉽게 말하면, 그림을 그릴 때 종이에 그리는 것처럼, 컴퓨터가 화면에 글자, 그림, 버튼 등을 그리는 과정을 렌더링이라고 생각하면 된다.

1. 먼저, 컴퓨터는 어떤 내용을 보여줄지 정한다. 예를 들어, "안녕하세요!"라는 글자와 그림이 필요하다고 생각한다면 (준비 단계)
2. 그 다음, 컴퓨터는 이 내용을 화면에 그린다. 이때 글자의 색깔이나 크기, 그림의 위치 등을 정해서 예쁘게 보여준다. (그림을 그리는 단계)
3. 그러다 만약 버튼을 클릭하거나 다른 행동을 하면, 컴퓨터는 다시 내용을 준비하고 다시 그리는 과정을 거치는데 이를 통해 화면이 바뀌고, 새로운 내용이 나타난다. (변화하는 단계)

이런 과정을 통해 웹 페이지에서 필요한 정보를 볼 수 있게 되는데 이걸 렌더링이라고 한다.

어떤 프레임워크, 라이브러리를 사용하든지 간에 맨 처음에 어떻게 보일지를 정하는 초기 렌더링이 필요하다.

초기 렌더링

리액트에서는 렌더링을 다루는 render라는 함수가 있다.

render() {...}

이 함수는 컴포넌트가 어떻게 생겼는지 정의하는 역할을 하는데 html 형식의 문자열을 반환하지 않고 뷰가 어떻게 생겼고 작동하는지에 대한 정보를 지닌 객체를 반환한다.

또, 컴포넌트 내부에는 또 다른 컴포넌트들이 들어갈 수 있는데 이 때 render 함수를 실행하면 그 내부에 있는 컴포넌트들도 재귀적(자기 자신을 호출)으로 렌더링한다. 이렇게 최상위 컴포넌트의 렌더링 작업이 끝나면 지니고 있는 정보들을 사용해서 HTML 마크업을 만들고 이를 우리가 정의하는 실제 페이지의 DOM 요소 안에 주입한다.

컴포넌트를 실제 페이지에 렌더링할 때는 분리된 두가지 절차를 따르는데 먼저 문자열 형태의 HTML 코드를 생성한 후 특정 DOM에 해당 내용을 주입하면 이벤트가 적용된다. 

리액트의 조화과정 (리액트가 화면에 보여줄 내용을 업데이트하는 방법.)

1. 초기 렌더링
처음에 리액트는 만들고 싶은 웹 페이지의 기본 모습을 그린다. 예를 들어, "안녕하세요! "라는 글자와 버튼이 있는 화면을 상상한다고 친다면, 이걸 처음으로 그리는 것을 "렌더링"이라고 한다.

2. 상태 변화 감지하기
이제 사용자가 버튼을 클릭하거나 다른 행동을 하면, 리액트는 "어, 누군가 클릭했는데?"라고 생각한다. 이때 리액트는 상태(state)라는 것을 확인하는데, 상태는 컴포넌트가 가지고 있는 정보를 의미한다.

3. 변경할 내용 정하기
리액트는 상태가 바뀌었는지 확인한 후, 어떤 부분을 바꿔야 할지를 정한다. 예를 들어, 버튼을 클릭했을 때 "안녕하세요!" 대신 "환영합니다!"로 바꿔야 한다고 생각해보자.

4. 조화 과정 시작하기
그럼 이제 리액트는 "조화"라는 과정을 시작한다. 조화는 리액트가 새로운 내용을 화면에 적용하는 과정을 말한다. 이때 리액트는 이전에 그린 내용과 새로운 내용을 비교해 낡은 내용은 지우고 새로운 내용을 그린다.

5. 새로운 화면 보여주기
마지막으로, 리액트는 준비한 새로운 내용을 화면에 보여준다. 그러면 버튼을 클릭한 후 "환영합니다!"라는 글자가 나타난다.

이렇게 리액트는 사용자의 행동에 따라 화면을 빠르고 효율적으로 업데이트할 수 있다. 이 과정 덕분에 웹 페이지에서 항상 최신 정보를 볼 수 있게 되는 것이다.

Virtual DOM  (가상의 돔)

가상 DOM은 리액트가 화면을 더 빠르고 효율적으로 업데이트할 수 있도록 돕는 특별한 도구라고 생각하면 된다.

DOM(Documet Object Model)?

  • 먼저, DOM은 웹 페이지의 구조를 표현하는 방식으로 브라우저는 HTML을 DOM으로 변환해서 화면에 보여준다.
  • 이 DOM은 우리가 웹 페이지의 내용과 구조를 조작할 수 있도록 해주는 일종의 지도 같은 것이다.

DOM의 문제점

  • 하지만 DOM을 직접 수정하는 것은 속도가 느릴 수 있다.
  • 만약 웹 페이지에 많은 변화가 생기면, 브라우저는 DOM을 매번 업데이트해야 하는데 그러면 시간이 오래 걸리고 성능이 떨어질 수 있는 문제점이 발생하게 된다.
더보기

여담

DOM 자체는 빠르다. DOM 자체를 읽고 쓸 때의 성능은 자바스크립트 객체를 처리할 때의 성능과 비교하여 다르지 않지만 웹 브라우저 단에서 DOM에 변화가 일어나 웹 브라우저가 CSS를 다시 연산하고, 레이아웃을 구성하고, 페이지를 리페인트 하는 과정에서 시간이 허비되는 것이다.

가상 DOM의 등장

그래서 가상 DOM이 등장했다. 가상 DOM은 실제 DOM의 가벼운 복사본이라고 생각하면 되는데 리액트는 이 가상 DOM을 사용해서 변화를 계산하고, 실제 DOM과 비교해 어떤 부분만 바꿔야 하는지를 정한다.

가상 DOM 동작 과정

  1. 변화 감지: 사용자가 버튼을 클릭하면, 리액트는 상태가 바뀌었다고 감지한다.
  2. 가상 DOM 업데이트: 리액트는 새로운 상태를 바탕으로 가상 DOM을 업데이트하는데 이때는 실제 DOM을 건드리지 않아서 빠르게 처리된다.
  3. 비교하기: 리액트는 이전의 가상 DOM과 새로운 가상 DOM을 비교해 어떤 부분이 달라졌는지를 확인한다.
  4. 최소한의 업데이트: 달라진 부분만 실제 DOM에 적용한다. 필요한 부분만 수정하니 성능이 좋아질 수 밖에 없다.

가상 DOM의 장점

  • DOM 업데이트를 추상화함으로써 DOM 처리 횟수를 최소화하고 효율적으로 진행한다.

+ Recent posts