본문으로 건너뛰기

안동민 개발노트

본문 시작

웹 개발의 변화와 React의 등장

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

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

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

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

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

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

문서 열람 중심의 웹에 부분 상호작용이 늘고 같은 데이터와 여러 UI를 맞추는 비용이 커지면서, React의 컴포넌트와 state 기반 렌더링 모델이 유용해진 흐름

WHY REACT

전달 방식이 아니라 UI 상태를 동기화하는 부담이 React 등장 배경의 핵심이다.

문서 중심 웹에서 React UI 모델까지의 개념 흐름 HTML과 CSS 문서 중심 화면에 이벤트와 요청 같은 부분 상호작용이 늘고, 하나의 데이터가 여러 UI에 영향을 주면서 수동 DOM 동기화 비용이 커진다. React는 화면을 컴포넌트로 나누고 state와 props로 렌더링 결과를 계산하는 모델을 제공한다. 문서 중심 화면 HTML · CSS 정적·서버 생성 모두 가능 부분 상호작용 이벤트 · 요청 DOM 일부 변경 동기화 비용 하나의 데이터 여러 UI에 영향 React UI 모델 component + state render 결과 계산
개념 흐름 상호작용이 늘수록 상태와 화면의 동기화가 별도 문제가 된다.
  1. 문서 중심 화면

    HTML과 CSS로 내용을 전달한다. 정적 파일과 서버 생성 HTML을 모두 사용할 수 있다.

  2. 부분 상호작용

    이벤트와 요청에 따라 JavaScript가 DOM 일부를 바꾼다.

  3. 동기화 비용 증가

    하나의 데이터가 여러 UI에 영향을 주면 모든 변경 경로를 맞춰야 한다.

  4. React의 UI 모델

    화면을 컴포넌트로 나누고 props와 state로 렌더링 결과를 계산한다.

정적 사이트, 서버 렌더링, SPA는 서로 다른 전달 구조다. 이 흐름은 그 용어를 등치하지 않고, 상태 동기화 부담이 커진 지점만 설명한다.

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

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

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

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

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


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

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

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

사용자 동작 뒤 필요한 DOM을 경로마다 직접 수정하는 흐름과, state 갱신 뒤 React가 컴포넌트를 render하고 달라진 부분을 DOM에 commit하는 흐름의 비교

UPDATE RESPONSIBILITY

차이는 DOM API의 유무가 아니라, 다음 화면을 누가 일관되게 계산하느냐에 있다.

직접 DOM 수정과 React render·commit 흐름 왼쪽은 사용자 동작 뒤 데이터를 바꾸고 관련 DOM 노드를 각각 찾아 수정한 다음 모든 화면 조각이 일치하는지 경로별로 확인한다. 오른쪽은 사용자 동작 뒤 state 갱신을 요청하고 React가 컴포넌트를 호출해 다음 UI를 계산한 뒤 달라진 부분을 DOM에 반영한다. 직접 DOM 갱신 React 상태 기반 렌더링 사용자 동작 클릭 · 입력 · 요청 완료 데이터 변경 애플리케이션 값 갱신 관련 DOM을 각각 수정 목록 · 합계 · 배지 · 버튼 경로별 일관성 확인 빠진 갱신이 없는지 개발자가 추적 사용자 동작 event handler 실행 state 갱신 요청 다음 렌더링 예약 Render 컴포넌트가 다음 UI를 계산 Commit 달라진 부분을 DOM에 반영

직접 DOM 갱신

  1. 사용자 동작

    클릭, 입력, 요청 완료를 처리한다.

  2. 데이터 변경

    애플리케이션 값을 갱신한다.

  3. DOM별 수정

    목록, 합계, 배지, 버튼을 필요한 경로에서 각각 바꾼다.

  4. 일관성 확인

    빠진 화면 갱신이 없는지 개발자가 추적한다.

React 상태 기반 렌더링

  1. 사용자 동작

    event handler가 실행된다.

  2. state 갱신 요청

    다음 렌더링을 예약한다.

  3. Render

    컴포넌트를 호출해 다음 UI 설명을 계산한다.

  4. Commit

    이전 결과와 달라진 부분을 DOM에 반영한다.

직접 DOM 조작은 작은 기능에 충분할 수 있다. 같은 상태를 읽는 화면 조각과 갱신 경로가 늘어날수록 React가 다음 UI를 계산하는 구조의 이점이 커진다.

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

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


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

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

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

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


Facebook에서 공개된 React

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

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

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

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