React

React의 실행 과정 자세히 살펴보기

코딩 코디네이터 2025. 4. 2. 08:00
반응형

React의 실행 과정 자세히 살펴보기

여러분 혹시 React 앱이 '딱 실행되는 순간'에 무슨 일이 일어나는지 궁금해본 적 있으세요?
우리가 매일 쓰는 이 프레임워크가 브라우저에서 어떻게 돌아가는지 안다면,
디버깅도 훨씬 쉬워지고 성능 최적화도 감이 잡히기 시작해요!

안녕하세요!

오늘은 React 앱의 실행 흐름에 대해 차근차근 뜯어보는 시간을 가져보려 해요.

React를 처음 접했을 때 가장 헷갈리는 부분 중 하나가 바로 "대체 어떤 순서로 실행되고 렌더링되는 거지?"라는 거잖아요.

그래서 준비했습니다. index.html부터 컴포넌트 렌더링, 가상 DOM과 diffing 알고리즘까지!

이미지를 곁들여 시각적으로도 쉽게 이해할 수 있도록 구성했으니까, React를 막 배우는 분들이라면 꼭! 끝까지 읽어주세요 😊

 

 

 

1. React 앱의 초기 로딩 🚀

React 앱은 단순한 HTML 문서처럼 보이지만, 사실 정교한 번들링 시스템렌더링 흐름을 포함하고 있어요. 앱을 브라우저에서 처음 실행할 때는 다음과 같은 단계가 순차적으로 이뤄집니다.

① HTML 파일 로드 📄

  • React 프로젝트는 index.html이 기본 진입점입니다.
  • 해당 HTML 파일은 매우 간단하지만 React 앱의 기반 DOM 요소를 담고 있어요.
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="/static/js/bundle.js"></script>
  </body>
</html>

이 중에서 <div id="root">가 가장 중요해요! React가 여기 안에 모든 UI를 렌더링하거든요.

② JavaScript 번들 로드 📦

이제 HTML을 다 불러왔으면, 본격적으로 JavaScript 번들 파일이 등장합니다. React 앱에서 작성한 모든 JS 코드들은 Webpack이나 Vite 같은 번들러를 통해 bundle.js로 합쳐져요.

  • 이 파일은 모든 React 컴포넌트, 상태 관리 코드, 라우팅 로직 등을 포함하고 있어요.
  • 브라우저가 이 JS 번들을 실행하면서 React 앱이 동작을 시작하죠.

🔎 정리: 초기 로딩 순서

단계 설명
1 index.html 로드 (root div 포함)
2 bundle.js 로딩 (JS 번들 실행)
3 React 앱 구동 시작

이 모든 일이 단 0.몇 초 안에 일어난다는 사실, 진짜 놀랍지 않나요? 😮

이제 다음으로 넘어가서 실제 React 컴포넌트가 DOM에 어떻게 렌더링되는지 확인해볼게요!

 

2. ReactDOM을 사용한 렌더링 🖥️

HTML이 모두 로드되고, JavaScript 번들이 실행되면 드디어 ReactDOM이 등장해요.

이 녀석이 하는 일은, 우리가 만든 React 컴포넌트를 브라우저의 DOM에 실제로 "마운트"하는 것입니다.

즉, 눈에 보이게 만들어주는 거죠!

① createRoot 사용법 (React 18 기준)

예전에는 ReactDOM.render를 썼지만, 이제는 React 18부터는 createRoot가 표준이 되었어요.

이건 동시성 기능(concurrent rendering)을 제대로 활용하기 위해 도입된 변화랍니다.

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

 

이 코드에서 createRoot는 브라우저 DOM에서 id가 root인 요소를 찾아 React 앱을 거기에 렌더링하겠다고 선언하는 거예요.

② App 컴포넌트는 왜 항상 위에 있을까?

  • App 컴포넌트는 React 앱의 진입점이자 최상위 컴포넌트입니다.
  • 이 안에서 다른 모든 컴포넌트들이 트리 구조로 하위에 배치되어요.

이 구조는 마치

HTML의 <body> 안에 섹션들이 있는 것

처럼 생각하면 돼요.

모든 페이지와 기능은 결국 이 App 컴포넌트 안에서 시작됩니다.

📌 실전 포인트 요약

항목 설명
createRoot React 18의 렌더링 시작점. 동시성 지원
App 컴포넌트 모든 컴포넌트 트리의 최상단 위치
root div 실제 HTML에서 React가 렌더링되는 공간

여기까지 오면 이제 화면에 React가 "짠!" 하고 나타나는 거죠.

다음 단계에서는 App 안에서 어떻게 컴포넌트들이 그려지는지 더 깊이 들어가 볼게요 🎨

 

3. 컴포넌트 구조와 JSX 변환 🎨

React의 진짜 매력은 바로 컴포넌트 기반 아키텍처에 있어요.

컴포넌트를 쌓고 연결하고 조립해서 하나의 앱을 완성하는 방식은 정말 직관적이고, 마치 레고 블록을 조립하는 것 같죠.

① 함수형 컴포넌트의 기본 구조

function App() {
  return (
    <div>
      <h1>Hello, React!</h1>
      <MyComponent />
    </div>
  );
}

 

이건 React 앱에서 가장 기본적인 구조예요.

<MyComponent />처럼 다른 컴포넌트를 끼워넣는 것도 엄청 간단하죠?

② JSX: JavaScript + XML?

React에서 사용하는 문법인 JSX는 말 그대로 JavaScript 안에서 HTML을 작성하는 느낌이에요.

근데 사실 이건

 

브라우저가 직접 해석할 수 없어요

 

  • Babel이 JSX를 JavaScript 코드로 변환해줘요.
  • JSX는 결국 React.createElement() 호출로 바뀌어요.

🧪 JSX 변환 예시

JSX 코드 JS 코드 (변환 결과)
<h1>Hello</h1> React.createElement('h1', null, 'Hello')
<div className="box"></div> React.createElement('div', { className: 'box' })

즉, JSX는 편하게 작성하기 위한 껍데기고, 진짜 중요한 건 React의 내부 함수들이라는 거예요.

🧩 정리: React 컴포넌트 핵심 요약

  1. React는 컴포넌트 단위로 UI를 구성
  2. JSX를 이용해 컴포넌트 작성
  3. JSX는 Babel을 통해 JS로 변환

다음 챕터에서는, 이 JSX로 만들어진 컴포넌트가 어떻게 가상 DOM을 만들고, 최종 화면으로 이어지는지 볼 거예요.

진짜 React의 마법이 시작되는 순간이죠! 🌳✨

 

4. 가상 DOM과 리렌더링 과정 🌳

React의 핵심을 단 하나만 꼽으라면, 단연 Virtual DOM(가상 DOM)이에요.

그냥 DOM을 쓰지 왜 굳이 가상을 만들었을까요?

그 이유는 바로... 성능입니다.

① Virtual DOM이란?

  • 메모리 상에 존재하는 DOM의 복사본이에요.
  • 실제 DOM을 직접 건드리지 않고, 변경 내용을 먼저 Virtual DOM에 적용해봐요.

왜 이렇게 하냐구요?

DOM 조작은 무겁고 느리니까요

React는 효율적으로 비교하고 최소한의 변경만 실제 DOM에 반영하려는 거예요.

② 리렌더링 흐름 정리 🔄

  1. 컴포넌트 상태(state)나 props가 변경됨
  2. 변경된 상태를 기반으로 새 Virtual DOM을 생성
  3. 이전 Virtual DOM과 새 Virtual DOM을 비교 (Diffing)
  4. 변경이 필요한 최소한의 실제 DOM 조작만 수행

📊 성능 비교 예시

방식 DOM 조작 범위 성능
기존 방식 전체 DOM 새로 그리기 느림
React 방식 변경된 부분만 반영 빠름

🔍 Diffing 알고리즘의 핵심

React는 O(n) 복잡도의 효율적인 알고리즘으로 이전 가상 DOM과 새 가상 DOM을 비교해요.

동일한 컴포넌트는 key를 기준으로 비교하고, 재사용 가능한 건 살리고 아닌 건 새로 생성하죠.

 

이 과정을 통해 React는 실제 DOM 변경을 최소화하면서도 UI를 항상 최신 상태로 유지해주는 거예요.

정말 효율적이죠?

다음은 상태(state)와 props가 이 흐름에 어떻게 영향을 주는지 알아봅시다 ⚙️

 

5. 상태(State)와 Props 흐름 ⚙️

React를 제대로 이해하려면 반드시 알아야 할 두 가지가 있어요.

바로 stateprops입니다.

이 둘이 어떻게 흐르고, 변경되며, UI를 업데이트시키는지 알면 React는 거의 마스터했다고 봐도 무방해요!

① Props: 외부로부터 받는 데이터

  • 부모 컴포넌트가 자식 컴포넌트에 전달하는 값이에요.
  • 읽기 전용이며 컴포넌트 내부에서 수정할 수 없어요.
function Welcome(props) {
  return <h1>안녕하세요, {props.name}님!</h1>;
}

② State: 내부에서 바뀌는 값

  • 컴포넌트 내부에서 생성되고 관리되는 데이터입니다.
  • useState 훅을 사용해서 선언하고 갱신해요.
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>현재 카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

📌 Props vs State 요약 비교

구분 Props State
역할 부모 → 자식 데이터 전달 컴포넌트 내부 데이터 관리
변경 가능 여부 읽기 전용 변경 가능 (setState 또는 set 함수)
리렌더링 변경 시 자식만 렌더링 변경 시 해당 컴포넌트 리렌더링

즉, props는 위에서 아래로 흐르는 값이고, state는 컴포넌트 내부에서 변화하는 값이에요.

이걸 이해하면 이제 사용자 입력이나 이벤트에 따라 어떻게 UI가 바뀌는지도 훨씬 잘 이해되실 거예요 😊

 

6. 이벤트 처리와 최종 업데이트 🔁

자, 이제 우리가 만든 React 앱에 사용자가 클릭하거나, 입력하거나, 마우스를 올리는 등의 이벤트가 발생할 때 무슨 일이 벌어지는지를 알아볼 차례예요.

이건 React 앱이 ‘살아있다’는 걸 보여주는 아주 중요한 부분이에요!

① 이벤트 바인딩 방식

HTML처럼 onclick 이런 거 안 써요!

React에서는 카멜 표기법으로 이벤트를 정의하고, 함수도 함께 넘겨야 해요.

function ButtonClicker() {
  const handleClick = () => {
    alert('버튼이 클릭되었습니다!');
  };

  return (
    <button onClick={handleClick}>클릭해보세요</button>
  );
}

② 상태(state) 변화 → 리렌더링

사용자가 이벤트를 일으키면, 대부분은 내부 상태(state)에 변화가 생겨요.

그러면 React는 전체 컴포넌트를 다시 렌더링하는 게 아니라, 변경된 부분만 골라서 가상 DOM을 통해 업데이트해요.

📌 실전 예제 - 카운터 버튼

function Counter() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <p>현재 숫자: {count}</p>
      <button onClick={() => setCount(count + 1)}>+ 증가</button>
    </div>
  );
}

 

여기서 버튼을 누를 때마다 count 값이 증가하고, 컴포넌트가 자동으로 다시 그려지는 거예요.

이게 React의 핵심 흐름이죠.

🔁 이벤트 → 상태 변화 → UI 반영 요약

  1. 사용자가 버튼 클릭 등 이벤트 발생
  2. 핸들러 함수 실행 → 상태 변화
  3. Virtual DOM이 새로운 UI 생성
  4. 변경된 부분만 DOM에 반영

📌 자주 쓰는 이벤트 목록

이벤트 종류 사용 예
onClick 버튼 클릭, 아이콘 클릭
onChange input, select 값 변경
onSubmit 폼 전송 시
onMouseEnter / Leave 호버 효과

이처럼 이벤트 처리 → 상태 변화 → 가상 DOM 생성 → DOM 업데이트까지!

이 모든 걸 React가 알아서 해준다는 거, 진짜 대단하지 않나요?

덕분에 우리는 비즈니스 로직에만 집중할 수 있죠! 🙌

 

🔚 React 실행 흐름, 이제 보이시나요?

지금까지 React 앱이 브라우저에서 실제로 어떻게 실행되는지, 그리고 그 속에서 어떤 로직이 일어나는지를 단계별로 살펴봤어요.

index.htmlbundle.jscreateRootJSX → 가상 DOM → 상태 변경 → 이벤트 → 리렌더링

이 전체 흐름이 머릿속에 하나의 선으로 연결되었다면,

여러분은 이제 진짜 React의 구조를 꿰뚫은 거예요! 🎉

 

처음엔 다소 복잡하게 느껴질 수도 있어요.

하지만 몇 번만 실습을 반복하면 자연스럽게 손이 기억하게 됩니다.

특히 상태와 props의 흐름, 그리고 가상 DOM의 작동 원리를 정확히 이해하면 훨씬 안정적인 코드와 성능 좋은 React 앱을 만들 수 있어요.

조금씩, 천천히, 꾸준히. React는 그렇게 여러분 편이 되어줄 거예요 😄

✅ 다음으로 하면 좋은 실습

  • React Developer Tools 확장 설치해서 Virtual DOM 직접 관찰해보기
  • 상태 변경에 따라 UI가 어떻게 변하는지 console.log로 추적해보기
  • 부모 → 자식 → 자식 → 다시 부모로 props/state 흐름 역추적해보기

 

반응형