icon
1장 : React 소개

React의 핵심 개념과 장점


우리는 지난 장에서 동적인 웹의 등장과 클라이언트 측 UI 개발의 복잡성 증대로 인해 자바스크립트 라이브러리 및 프레임워크의 필요성이 대두되었음을 살펴보았습니다. 이제는 그 중심에 서 있는 리액트(React)가 어떤 철학을 가지고 있으며, 어떠한 핵심 개념들을 통해 웹 개발을 혁신했는지, 그리고 이로 인해 얻을 수 있는 장점들은 무엇인지 깊이 있게 탐구해 볼 차례입니다.


UI 개발을 위한 선언적 방식

리액트의 가장 핵심적인 특징 중 하나는 바로 선언적(Declarative) 방식의 UI 개발을 지향한다는 점입니다. 이는 명령형(Imperative) 방식과 대비되는 개념인데요, 잠시 두 방식의 차이를 비교해볼까요?

  • 명령형(Imperative) 방식: "어떻게(How) 할 것인가"에 초점을 맞춥니다. 개발자가 직접 단계별로 DOM을 조작하여 UI의 변화를 지시합니다. 예를 들어, "이 버튼을 찾아 클릭 이벤트를 추가하고, 클릭 시 텍스트를 '클릭됨'으로 변경하고, 글자색을 빨간색으로 바꿔라"와 같이 상세한 지시를 내리는 방식입니다. 코드가 복잡해질수록 상태 관리와 버그 추적이 어려워지는 경향이 있습니다.

  • 선언적(Declarative) 방식: "무엇을(What) 보여줄 것인가"에 초점을 맞춥니다. 개발자는 원하는 UI의 최종 상태를 선언하고, 리액트가 내부적으로 그 상태에 도달하기 위한 최적의 방법을 찾아 DOM을 업데이트합니다. 예를 들어, "버튼의 isActive 상태가 true이면 '활성'이라는 텍스트를 파란색으로 보여주고, false이면 '비활성'이라는 텍스트를 회색으로 보여줘"와 같이 선언합니다. 그러면 isActive 값이 변경될 때마다 리액트가 알아서 해당 상태에 맞는 UI를 그려줍니다.

리액트 개발자는 원하는 UI의 모습만 선언하면 됩니다. 데이터가 변경되면, 리액트는 그 데이터를 기반으로 UI가 어떻게 보일지 다시 선언하고, 이전 상태와 현재 상태를 비교하여 변경된 부분만 효율적으로 업데이트합니다. 이러한 선언적 방식 덕분에 개발자는 복잡한 DOM 조작에 신경 쓸 필요 없이, 오직 애플리케이션의 '상태'에만 집중하여 코드를 작성할 수 있게 됩니다. 이는 코드의 가독성을 높이고, 예측 가능한 UI 업데이트를 가능하게 하여 개발 생산성과 유지보수성을 크게 향상시킵니다.


컴포넌트 기반 아키텍처

리액트의 또 다른 강력한 특징은 모든 것을 컴포넌트(Component) 라는 조각으로 나누어 개발한다는 점입니다. 컴포넌트는 UI를 구성하는 독립적이고 재사용 가능한 최소 단위입니다. 마치 레고 블록처럼, 작은 컴포넌트들을 조립하여 복잡한 UI를 구축할 수 있습니다.

예를 들어, 웹페이지를 만든다고 상상해 보세요. 헤더, 내비게이션 바, 사이드바, 게시물 목록, 댓글 입력창 등 각각의 UI 요소를 하나의 컴포넌트로 만들 수 있습니다.

  • 재사용성(Reusability): 한 번 만든 컴포넌트는 다른 페이지나 다른 프로젝트에서도 쉽게 재사용할 수 있습니다. 예를 들어 '버튼' 컴포넌트를 만들어 두면, 웹사이트의 모든 버튼에 동일한 스타일과 기능을 적용하면서도, 필요에 따라 다양한 종류의 버튼을 쉽게 만들어낼 수 있습니다.
  • 유지보수성(Maintainability): 각 컴포넌트는 독립적으로 작동하므로, 특정 부분에 문제가 발생하더라도 전체 애플리케이션에 미치는 영향을 최소화하고, 문제 해결이 용이해집니다.
  • 모듈성(Modularity): 복잡한 UI를 작은 단위로 분리하여 개발함으로써, 여러 개발자가 동시에 다른 컴포넌트를 개발할 수 있어 협업 효율성을 높일 수 있습니다.

이러한 컴포넌트 기반의 접근 방식은 대규모 애플리케이션 개발에 특히 유리하며, 코드의 응집도를 높이고 결합도를 낮춰 소프트웨어의 전반적인 품질을 향상시킵니다.


가상 DOM

"데이터가 변경되면 UI를 효율적으로 업데이트한다"는 리액트의 선언적 방식을 가능하게 하는 핵심 기술 중 하나가 바로 가상 DOM (Virtual DOM) 입니다.

일반적으로 웹 브라우저는 HTML 문서를 파싱하여 화면에 보여주기 위한 트리 형태의 객체 모델을 만듭니다. 이것을 DOM(Document Object Model) 이라고 부릅니다. 그런데 DOM을 직접 조작하는 것은 매우 비용이 많이 드는(costly) 작업입니다. DOM이 변경될 때마다 브라우저는 CSS를 다시 계산하고, 레이아웃을 다시 배치하며, 화면을 다시 그리는(reflow, repaint) 과정을 거쳐야 합니다. 잦은 DOM 조작은 웹 애플리케이션의 성능 저하로 이어질 수 있습니다.

리액트는 이러한 문제를 해결하기 위해 가상 DOM이라는 개념을 도입했습니다. 가상 DOM은 실제 DOM의 경량화된 사본이라고 생각할 수 있습니다. 리액트는 실제 DOM을 직접 조작하는 대신, 다음과 같은 과정을 거칩니다.

데이터 변경: 컴포넌트의 상태(데이터)가 변경됩니다.

가상 DOM 생성: 리액트는 변경된 데이터를 기반으로 새로운 가상 DOM을 생성합니다.

이전 가상 DOM과 비교: 새로 생성된 가상 DOM을 이전 가상 DOM과 효율적인 알고리즘(Diffing Algorithm)을 사용하여 비교합니다.

최소한의 변경사항만 실제 DOM에 적용: 두 가상 DOM 간의 차이점(변경사항)만을 감지하여, 실제 DOM에 해당 부분만 최소한으로 업데이트합니다.

이 과정을 통해 리액트는 불필요한 DOM 조작을 최소화하고, 화면 렌더링 성능을 최적화할 수 있습니다. 개발자는 실제 DOM 조작에 대한 고민 없이, 그저 데이터만 변경하면 리액트가 알아서 가장 효율적인 방식으로 UI를 업데이트해주는 것이죠. 이것이 바로 리액트 애플리케이션이 빠르고 부드럽게 작동하는 핵심적인 비결 중 하나입니다.


단방향 데이터 흐름

리액트는 단방향 데이터 흐름 (Unidirectional Data Flow) 을 지향합니다. 이는 데이터가 부모 컴포넌트에서 자식 컴포넌트로만 흐르는 것을 의미합니다. 자식 컴포넌트는 부모로부터 전달받은 props (프로퍼티)를 통해 데이터를 읽을 수만 있고, 직접적으로 부모의 데이터를 변경할 수는 없습니다. 만약 자식 컴포넌트가 부모의 데이터를 변경해야 할 필요가 있다면, 부모가 전달해준 함수를 호출하여 부모 컴포넌트 내부에서 상태를 변경하도록 요청해야 합니다.

이러한 단방향 데이터 흐름은 데이터의 변화를 추적하기 매우 용이하게 만듭니다. 데이터가 어느 방향으로든 자유롭게 흐를 수 있다면, 예측 불가능한 버그가 발생하기 쉽고, 문제의 원인을 파악하기 어려워집니다. 하지만 단방향 데이터 흐름은 데이터의 흐름을 명확하게 제한함으로써 애플리케이션의 안정성을 높이고, 디버깅을 훨씬 수월하게 만듭니다.


React의 장점 요약

지금까지 살펴본 리액트의 핵심 개념들을 바탕으로, 리액트가 가진 주요 장점들을 다시 한번 정리해 볼까요?

  • 높은 생산성: 선언적 UI, 컴포넌트 재사용성, 가상 DOM을 통한 효율적인 업데이트는 개발자가 UI 구현에 드는 노력을 줄이고 핵심 비즈니스 로직에 집중할 수 있도록 하여 생산성을 크게 향상시킵니다.
  • 뛰어난 성능: 가상 DOM을 통해 불필요한 DOM 조작을 최소화하여 빠르고 부드러운 사용자 경험을 제공합니다.
  • 쉬운 유지보수: 컴포넌트 기반의 모듈화된 구조와 단방향 데이터 흐름은 코드의 가독성을 높이고, 복잡성을 줄여 장기적인 유지보수를 용이하게 합니다.
  • 활발한 생태계와 커뮤니티: 페이스북이 개발하고 관리하며, 전 세계 수많은 개발자들이 사용하고 있는 만큼 방대한 자료와 라이브러리, 그리고 활발한 커뮤니티를 자랑합니다. 문제 발생 시 도움을 받기 용이하며, 끊임없이 새로운 기술과 도구들이 개발되고 있습니다.
  • 크로스 플랫폼 개발 가능성: 리액트의 핵심 개념은 웹뿐만 아니라, 모바일 앱(React Native)이나 데스크톱 앱(Electron과 연동) 개발에도 확장될 수 있어 학습의 시너지가 큽니다.

이처럼 리액트는 현대 웹 애플리케이션 개발에 있어 강력하고 효율적인 도구로 자리매김했습니다.