본문 바로가기

웹 개발의 변화와 React의 등장

문서 전달 방식과 UI 상호작용을 구분하고, 상태 동기화 문제에서 React의 컴포넌트·렌더링 모델이 나온 배경을 이해합니다.

처음 웹 개발을 시작하면 화면만 잘 나오면 된 것 아닌가?라는 생각이 자연스럽게 듭니다.

작은 페이지에서는 HTML과 CSS에 약간의 JavaScript를 더하는 것만으로 충분할 수 있습니다. 하지만 같은 데이터가 목록, 배지, 버튼처럼 여러 화면 조각에 동시에 나타나고 사용자 동작에 따라 계속 바뀌면 문제가 달라집니다.

개발자는 데이터뿐 아니라 어떤 DOM을 어떤 순서로 바꿨는지도 함께 추적해야 합니다. 버튼 하나를 바꿨는데 다른 영역은 이전 값을 보여주거나, 데이터는 갱신됐지만 화면 일부가 그대로 남는 버그가 이때 생깁니다.

React는 이런 UI 구조 문제를 다루는 라이브러리입니다. 화면을 컴포넌트로 나누고, props와 state를 입력으로 받아 지금 보여 줄 UI를 계산하도록 돕습니다.

이 장에서는 HTML의 요소·속성, CSS의 선택자, JavaScript의 함수·객체·이벤트를 알고 있다고 가정합니다. 아직 낯설다면 HTML 문서 구조와 JavaScript 기초를 먼저 확인하세요. state는 화면이 기억해야 하는 데이터이고, props는 부모가 컴포넌트에 전달하는 입력입니다. 두 값의 실제 문법은 다음 절의 작은 예제에서 연결합니다.

다음 흐름은 React가 모든 페이지의 기본값이라는 뜻이 아닙니다. 화면의 상호작용과 상태 동기화 부담이 커질수록 이런 모델의 이점이 커졌다는 배경을 보여 줍니다.

정적 사이트·서버 렌더링·SPA는 서로 다른 전달 구조입니다. 이 그림은 상태 동기화 부담의 흐름만 설명하며, 모든 페이지에 React가 필요하다는 뜻이 아닙니다.

React · UI와 실행의 관계

같은 상태가 여러 UI를 바꾸면 동기화가 필요합니다

장바구니 수량이 바뀌면 목록·합계·배지·버튼이 함께 바뀝니다. 현재 props와 state에서 각 컴포넌트의 UI를 계산하는 모델을 비교합니다.

문서 중심 화면과 UI 동기화의 개념 흐름상태 동기화 부담을 설명하는4노드3간선 개념 흐름이다. 문서 중심→부분 상호작용→동기화 부담→React UI모델이며, 정적·서버생성·SPA를 같은 분류 축으로 등치하거나 React 도입이 필수라는 시간선으로 읽지 않는다.
문서 중심 화면HTML · CSS정적 · 서버 생성 모두
연결 관계문서 중심 화면 · HTML · CSS · 정적 · 서버 생성 모두 → 부분 상호작용 · 이벤트 · 요청 · DOM 일부 변경
부분 상호작용이벤트 · 요청DOM 일부 변경
연결 관계부분 상호작용 · 이벤트 · 요청 · DOM 일부 변경 → 동기화 부담 · 하나의 데이터 · 여러 UI에 영향
동기화 부담하나의 데이터여러 UI에 영향
연결 관계동기화 부담 · 하나의 데이터 · 여러 UI에 영향 → React UI 모델 · 컴포넌트 · state · props로 UI 계산
React UI 모델컴포넌트 · stateprops로 UI 계산
문서 중심 화면과 UI 동기화의 개념 흐름 · 모바일상태 동기화 부담을 설명하는4노드3간선 개념 흐름이다. 문서 중심→부분 상호작용→동기화 부담→React UI모델이며, 정적·서버생성·SPA를 같은 분류 축으로 등치하거나 React 도입이 필수라는 시간선으로 읽지 않는다. 모바일에서도 같은 연결과 분기·되돌림 대상을 유지한다.
문서 중심 화면HTML · CSS정적 · 서버 생성 모두
연결 관계문서 중심 화면 · HTML · CSS · 정적 · 서버 생성 모두 → 부분 상호작용 · 이벤트 · 요청 · DOM 일부 변경
부분 상호작용이벤트 · 요청DOM 일부 변경
연결 관계부분 상호작용 · 이벤트 · 요청 · DOM 일부 변경 → 동기화 부담 · 하나의 데이터 · 여러 UI에 영향
동기화 부담하나의 데이터여러 UI에 영향
연결 관계동기화 부담 · 하나의 데이터 · 여러 UI에 영향 → React UI 모델 · 컴포넌트 · state · props로 UI 계산
React UI 모델컴포넌트 · stateprops로 UI 계산

정적 사이트·서버 렌더링·SPA는 서로 다른 전달 구조입니다. 이 그림은 상태 동기화 부담의 흐름만 설명하며, 모든 페이지에 React가 필요하다는 뜻이 아닙니다.


문서 전달 방식과 화면 상호작용은 다른 축입니다

초기의 많은 웹사이트가 문서 열람 중심이었고 페이지 이동 때 전체 문서를 다시 받았던 것은 사실입니다. 다만 정적 웹, 서버 렌더링, 동적 UI, SPA는 같은 기준으로 나뉘는 말이 아닙니다.

  • 정적 사이트는 미리 만들어 둔 HTML 같은 파일을 요청에 응답합니다. 그 문서에도 JavaScript 상호작용을 넣을 수 있습니다.
  • 서버 렌더링 사이트는 요청과 데이터에 따라 서버가 HTML을 만들 수 있습니다. 페이지 이동 때 전체 문서를 다시 받아도 내용은 동적으로 생성될 수 있습니다.
  • SPA(Single Page Application)는 보통 첫 문서를 받은 뒤 클라이언트 JavaScript가 라우팅과 화면 일부 갱신을 담당하는 구조를 가리킵니다.

현대 웹 애플리케이션은 이 방식을 섞기도 합니다. 서버에서 처음 HTML을 만들고 브라우저에서 상호작용을 이어 갈 수 있으며, React 자체도 SPA만을 뜻하지 않습니다.

중요한 변화는 브라우저가 단순히 문서를 보여 주는 데서 그치지 않고, 입력·요청·필터·편집처럼 오래 이어지는 UI 상태를 다루게 되었다는 점입니다.


직접 DOM을 고칠 때 생기는 동기화 부담

작은 메뉴나 독립적인 탭처럼 상태가 단순한 기능은 순수 JavaScript로 명확하게 구현할 수 있습니다. 직접 DOM을 조작하는 방식 자체가 잘못된 것은 아닙니다.

어려움은 하나의 상태가 여러 UI에 영향을 줄 때 커집니다. 예를 들어 장바구니 수량이 바뀌면 목록의 수량, 합계, 헤더 배지, 결제 버튼 상태를 모두 같은 값에 맞춰야 합니다. 각 이벤트 처리기가 필요한 요소를 찾아 따로 고치면 갱신 경로가 늘어날수록 빠뜨린 DOM 변경을 찾기 어려워집니다.

명령형 DOM 갱신과 React 렌더링 비교 — 상태 추적

장바구니 수량 하나의 변경이 목록/합계/배지/버튼에 반영되는 직접 DOM 경로와 state/render/commit 경로를 독립 비교한다. 현재 값/요청/DOM의 차이를 추적할 가치가 있다.

두 경로는 비교 대상이며 위에서 아래로 모두 실행하는 순서가 아닙니다. React의 render는 컴포넌트 호출로 UI를 계산하며 commit은 필요한 DOM 변경을 반영합니다. 상태 소유권과 입력 검증은 개발자가 설계합니다.

React · UI와 실행의 관계

수동 DOM 갱신과 상태 기반 렌더링은 책임을 다르게 나눕니다

같은 장바구니 수량을 읽는 화면 영역을 비교합니다. 직접 갱신에서는 각각의 DOM 수정 경로를 맞추며 React에서는 setter 요청 뒤 render와 commit을 구분합니다.

직접 DOM 수정과 React render·commit독립적인 두4노드3간선 갱신 경로(총8노드6간선)다. 왼쪽은 데이터 뒤 관련DOM을 직접 갱신하고 일관성을 확인한다. 오른쪽은 setter 요청→render의UI계산→commit의DOM반영이다. 두 경로 사이에 간선을 그리지 않으며 모바일 위아래 비교도 순차 실행이 아니다.직접 DOM 갱신사용자 동작클릭 · 입력 · 요청데이터 변경앱의 값 갱신DOM별 수정목록 · 합계배지 · 버튼일관성 확인빠진 갱신 추적React 상태 기반사용자 동작이벤트 함수 실행state 갱신 요청setter 호출Render다음 UI 계산Commit달라진 DOM 반영
서로 다른 두 갱신 경로 · 모바일독립적인 두4노드3간선 갱신 경로(총8노드6간선)다. 왼쪽은 데이터 뒤 관련DOM을 직접 갱신하고 일관성을 확인한다. 오른쪽은 setter 요청→render의UI계산→commit의DOM반영이다. 두 경로 사이에 간선을 그리지 않으며 모바일 위아래 비교도 순차 실행이 아니다.직접 DOM 갱신사용자 동작클릭 · 입력 · 요청데이터 변경앱의 값 갱신DOM별 수정목록 · 합계배지 · 버튼일관성 확인빠진 갱신 추적React 상태 기반사용자 동작이벤트 함수 실행state 갱신 요청setter 호출Render다음 UI 계산Commit달라진 DOM 반영

두 경로는 비교 대상이며 위에서 아래로 모두 실행하는 순서가 아닙니다. React의 render는 컴포넌트 호출로 UI를 계산하며 commit은 필요한 DOM 변경을 반영합니다. 상태 소유권과 입력 검증은 개발자가 설계합니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
  • 본문의 단가 1,200원·수량 2→3 예제를 선택합니다. 직접 DOM 갱신과 React 경로는 같은 입력과 결과의 독립 비교이며, 주문 가능 여부와 서버 가격 확정은 이 화면 관찰 밖입니다.
관계도의 보충 설명
원도표의 전체 관계·조건·설명
구분내용
전체 관계·조건 설명독립적인 두 갱신 경로는 각각 노드 4개와 간선 3개로 구성된다(총 노드 8개·간선 6개). 왼쪽은 데이터 뒤 관련 DOM을 직접 갱신하고 일관성을 확인한다. 오른쪽은 setter 요청→render의 UI 계산→commit의 DOM 반영이다. 두 경로 사이에 간선을 그리지 않으며 모바일 위아래 비교도 순차 실행이 아니다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
수량 2의 화면qty: 2 / 합계·배지·버튼: 2,400원 · 2 · 활성수량 2에서 합계는 2,400원이고 배지는 2, 결제 버튼은 활성이다합계 1,200×2와 버튼 조건 qty>0은 같은 수량에서 계산한다
수량 3으로 변경 요청요청 qty: 3 / React commit 전 DOM: 수량 2 · 합계 2,400원직접 경로는 관련 DOM을 수정하고 React 경로는 수량 3을 요청해 다음 UI를 계산한다setter 요청과 render 계산은 commit 전 DOM을 곧바로 바꾸지 않는다. 직접 DOM 경로와 독립 비교다
수량 3의 화면qty·배지: 3 · 3 / 합계·버튼: 3,600원 · 활성직접 DOM 갱신 또는 React commit 뒤 수량과 배지는 3, 합계는 3,600원이다React commit 또는 직접 DOM 갱신이 관련 표시를 같은 qty 3에 맞춘다

명령형 DOM 갱신과 React 렌더링 비교 — 상태 추적

장바구니 수량 하나의 변경이 목록/합계/배지/버튼에 반영되는 직접 DOM 경로와 state/render/commit 경로를 독립 비교한다. 현재 값/요청/DOM의 차이를 추적할 가치가 있다.

두 경로는 비교 대상이며 위에서 아래로 모두 실행하는 순서가 아닙니다. React의 render는 컴포넌트 호출로 UI를 계산하며 commit은 필요한 DOM 변경을 반영합니다. 상태 소유권과 입력 검증은 개발자가 설계합니다.

React · UI와 실행의 관계

수동 DOM 갱신과 상태 기반 렌더링은 책임을 다르게 나눕니다

같은 장바구니 수량을 읽는 화면 영역을 비교합니다. 직접 갱신에서는 각각의 DOM 수정 경로를 맞추며 React에서는 setter 요청 뒤 render와 commit을 구분합니다.

직접 DOM 수정과 React render·commit독립적인 두4노드3간선 갱신 경로(총8노드6간선)다. 왼쪽은 데이터 뒤 관련DOM을 직접 갱신하고 일관성을 확인한다. 오른쪽은 setter 요청→render의UI계산→commit의DOM반영이다. 두 경로 사이에 간선을 그리지 않으며 모바일 위아래 비교도 순차 실행이 아니다.직접 DOM 갱신사용자 동작클릭 · 입력 · 요청데이터 변경앱의 값 갱신DOM별 수정목록 · 합계배지 · 버튼일관성 확인빠진 갱신 추적React 상태 기반사용자 동작이벤트 함수 실행state 갱신 요청setter 호출Render다음 UI 계산Commit달라진 DOM 반영
서로 다른 두 갱신 경로 · 모바일독립적인 두4노드3간선 갱신 경로(총8노드6간선)다. 왼쪽은 데이터 뒤 관련DOM을 직접 갱신하고 일관성을 확인한다. 오른쪽은 setter 요청→render의UI계산→commit의DOM반영이다. 두 경로 사이에 간선을 그리지 않으며 모바일 위아래 비교도 순차 실행이 아니다.직접 DOM 갱신사용자 동작클릭 · 입력 · 요청데이터 변경앱의 값 갱신DOM별 수정목록 · 합계배지 · 버튼일관성 확인빠진 갱신 추적React 상태 기반사용자 동작이벤트 함수 실행state 갱신 요청setter 호출Render다음 UI 계산Commit달라진 DOM 반영

두 경로는 비교 대상이며 위에서 아래로 모두 실행하는 순서가 아닙니다. React의 render는 컴포넌트 호출로 UI를 계산하며 commit은 필요한 DOM 변경을 반영합니다. 상태 소유권과 입력 검증은 개발자가 설계합니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
  • 본문의 단가 1,200원·수량 2→3 예제를 선택합니다. 직접 DOM 갱신과 React 경로는 같은 입력과 결과의 독립 비교이며, 주문 가능 여부와 서버 가격 확정은 이 화면 관찰 밖입니다.

관계도의 보충 설명

원도표의 전체 관계·조건·설명
구분내용
전체 관계·조건 설명독립적인 두 갱신 경로는 각각 노드 4개와 간선 3개로 구성된다(총 노드 8개·간선 6개). 왼쪽은 데이터 뒤 관련 DOM을 직접 갱신하고 일관성을 확인한다. 오른쪽은 setter 요청→render의 UI 계산→commit의 DOM 반영이다. 두 경로 사이에 간선을 그리지 않으며 모바일 위아래 비교도 순차 실행이 아니다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
수량 2의 화면qty: 2 / 합계·배지·버튼: 2,400원 · 2 · 활성수량 2에서 합계는 2,400원이고 배지는 2, 결제 버튼은 활성이다합계 1,200×2와 버튼 조건 qty>0은 같은 수량에서 계산한다
수량 3으로 변경 요청요청 qty: 3 / React commit 전 DOM: 수량 2 · 합계 2,400원직접 경로는 관련 DOM을 수정하고 React 경로는 수량 3을 요청해 다음 UI를 계산한다setter 요청과 render 계산은 commit 전 DOM을 곧바로 바꾸지 않는다. 직접 DOM 경로와 독립 비교다
수량 3의 화면qty·배지: 3 · 3 / 합계·버튼: 3,600원 · 활성직접 DOM 갱신 또는 React commit 뒤 수량과 배지는 3, 합계는 3,600원이다React commit 또는 직접 DOM 갱신이 관련 표시를 같은 qty 3에 맞춘다

React에서는 이벤트 처리기가 state 갱신을 요청하면 렌더링이 예약됩니다. React는 컴포넌트를 호출해 다음 UI 설명을 계산하고, 이전 결과와 달라진 부분을 DOM에 반영합니다. 따라서 render는 곧 DOM을 전부 다시 만드는 작업이라는 뜻이 아닙니다.

이 모델에서도 상태를 어디에 둘지, 어떤 값을 state로 저장할지, 컴포넌트 경계를 어떻게 나눌지는 개발자가 결정해야 합니다. React는 구조를 제공하지만 올바른 상태 설계를 대신해 주지는 않습니다.

예시

한 종류의 상품 가격을 1,200원으로 고정하고 장바구니 수량을 2에서 3으로 바꾸었다고 가정합니다. 수량 표시와 헤더 배지는 둘 다 3, 합계는 1,200 × 3 = 3,600원, 결제 버튼은 수량이 0보다 커서 활성 상태여야 합니다. 합계를 별도의 데이터로 계속 수정하기보다 현재 수량에서 계산하면 서로 다른 합계를 저장할 기회를 줄일 수 있습니다. 실제 주문 가능 여부·가격 확정은 서버의 판단이 필요한 별도 조건이며, 이 사례는 화면 안의 동기화만 다룹니다.


UI 라이브러리가 유리해지는 조건

UI 라이브러리를 도입하면 컴포넌트 경계, 선언적 렌더링, 생태계 도구를 얻는 대신 학습·빌드·의존성 비용이 생깁니다. 그래서 기능의 개수보다 화면이 어떻게 변하고 팀이 그 변화를 어떻게 관리해야 하는지를 먼저 봐야 합니다.

React 도입은 상태의 연결 범위와 변경 비용으로 판단합니다

ADOPTION CONDITIONS

React 도입은 상태의 연결 범위와 변경 비용으로 판단합니다

고정 콘텐츠·작은 상호작용부터 상태 공유·반복 UI·팀 변경까지 비교합니다. 이점과 학습·빌드·의존성 비용을 함께 보며, 서버 렌더링과 함께 사용할 수도 있습니다.

핵심 신호: 한 값이 여러 화면 영역에 영향

장바구니 수량 하나가 목록·합계·배지·버튼을 바꾼다면 상태 소유권과 갱신 경로를 먼저 정합니다.

도구의 유행보다 상태의 연결 범위와 변경 비용을 먼저 본다.
화면 조건 관찰할 신호 단순한 시작점 React의 이점 또는 비용
고정 콘텐츠 중심 읽기 흐름이 중심이고 변하는 로컬 상태가 거의 없다. 의미 있는 HTML, CSS, 필요한 작은 스크립트 컴포넌트 런타임과 빌드 구성이 오히려 추가 비용일 수 있다.
독립된 작은 상호작용 메뉴나 탭처럼 한 영역 안에서 상태가 끝난다. 점진적 향상 또는 작은 JavaScript 모듈 동작이 반복·확장될 때 컴포넌트화의 가치가 생긴다.
여러 영역이 상태 공유 하나의 값이 목록, 합계, 배지, 버튼에 함께 영향을 준다. 상태의 단일 출처와 갱신 경로부터 설계 state를 기준으로 다음 UI를 계산해 수동 DOM 동기화를 줄인다.
반복되는 대화형 UI 카드, 폼, 모달, 목록을 데이터로 반복하고 조합한다. 재사용 경계와 입력·출력 계약 정의 컴포넌트와 props로 구조를 드러내고 테스트 단위를 나눌 수 있다.
변경이 잦은 팀 제품 여러 사람이 화면 책임을 나누고 기능을 계속 확장한다. 팀 규칙, 품질 기준, 유지 주체 합의 공통 모델과 생태계를 얻지만 학습·의존성·업그레이드 비용도 맡는다.

고정 콘텐츠 중심

관찰 읽기 중심이고 변하는 로컬 상태가 거의 없습니다.

시작 의미 있는 HTML·CSS와 필요한 작은 스크립트

판단 React 런타임과 빌드 구성이 추가 비용일 수 있습니다.

독립된 작은 상호작용

관찰 메뉴·탭처럼 한 영역 안에서 상태가 끝납니다.

시작 점진적 향상 또는 작은 JavaScript 모듈

판단 동작이 반복·확장되면 컴포넌트화의 가치가 생깁니다.

여러 영역이 상태 공유

관찰 한 값이 목록·합계·배지·버튼에 함께 영향을 줍니다.

시작 상태의 단일 출처와 갱신 경로부터 설계

판단 state에서 다음 UI를 계산해 수동 DOM 동기화를 줄입니다.

반복되는 대화형 UI

관찰 카드·폼·모달·목록을 데이터로 반복하고 조합합니다.

시작 재사용 경계와 입력·출력 계약 정의

판단 컴포넌트와 props로 구조·테스트 단위를 나눕니다.

변경이 잦은 팀 제품

관찰 여러 사람이 화면 책임을 나누고 기능을 계속 확장합니다.

시작 팀 규칙·품질 기준·유지 주체 합의

판단 공통 모델과 생태계를 얻고 학습·의존성·업그레이드 비용을 맡습니다.

고정 콘텐츠가 중심이고 상호작용이 작다면 HTML, CSS, 작은 스크립트가 더 단순할 수 있습니다. 반대로 같은 상태를 여러 컴포넌트가 읽고, 반복 UI가 많으며, 화면 변경을 여러 사람이 나눠 맡는다면 React의 구조적 이점이 커집니다.


Facebook에서 공개된 React

Facebook은 데이터가 계속 바뀌는 큰 UI를 컴포넌트로 조합하고 일관되게 갱신하기 위해 React를 개발했고, 2013년에 오픈 소스로 공개했습니다.

당시 공식 소개에서도 React는 MVC 프레임워크가 아니라 조합 가능한 사용자 인터페이스를 만드는 라이브러리로 설명되었습니다. 핵심 제안은 개발자가 DOM 변경 명령을 일일이 나열하기보다, 데이터에 맞는 UI가 무엇인지 컴포넌트로 표현하도록 책임을 옮기는 것이었습니다.

React가 모든 웹 문제를 해결하는 것은 아닙니다. 하지만 컴포넌트, state, render와 commit이라는 모델은 상호작용이 많은 UI를 설명하고 변경 범위를 나누는 강력한 공통 언어를 제공합니다.

다음 절에서는 이 배경 위에서 React의 핵심 특징과 각 개념이 실제 코드에서 어떤 역할을 하는지 살펴봅니다.

혼자 판단하기

같은 장바구니에서 수량을 0으로 바꾸었는데 목록만 0이고 배지는 3, 합계는 3,600원, 결제 버튼은 활성 상태로 남았습니다. 지금 바뀌어야 할 세 결과와 그 계산 근거를 적으세요. 고정 안내문에 독립된 메뉴 하나만 있는 페이지에도 이 문제를 근거로 React가 반드시 필요하다고 결론 낼 수 있을까요?

공유 상태와 도입 조건의 풀이

배지는 0, 합계는 1,200 × 0 = 0원, 결제 버튼은 비활성 상태여야 합니다. 세 화면 영역이 같은 수량을 읽는데 일부 갱신이 빠진 문제입니다. 컴포넌트와 상태의 단일 출처는 이런 변경 경로를 읽기 쉽게 만들지만, 상태 소유권과 입력 조건을 직접 정해야 합니다. 독립된 메뉴 하나는 작은 스크립트로도 관리할 수 있으므로, 장바구니의 동기화 부담을 모든 페이지의 도입 이유로 일반화하지 않습니다.