1. 리액트 소개
리액트(React)는 페이스북(현 Meta)에서 개발한 사용자 인터페이스(UI)를 구축하기 위한 자바스크립트 라이브러리이다. 웹뿐만 아니라, 리액트 네이티브(React Native)를 통해 모바일 앱 인터페이스까지 구축할 수 있다.
프레임워크가 아닌 라이브러리인 이유
리액트는 종종 프레임워크로 오해받지만, 스스로를 라이브러리라고 정의한다. 그 이유는 다음과 같다.
- 최소한의 기능만 내장: 리액트는 UI를 렌더링하고 상태를 관리하는 핵심 기능에만 집중한다. 라우팅(화면 전환), 전역 상태 관리, 데이터 통신과 같은 필수적인 기능들은 내장되어 있지 않아
React Router,Redux,Axios와 같은 서드파티(Third-party) 라이브러리에 의존해야 한다. - 높은 자유도와 책임: 프레임워크는 정해진 구조와 규칙을 따르도록 강제하는 반면, 리액트는 개발자에게 높은 수준의 자유도를 제공한다. 프로젝트의 구조, 디자인 패턴, 사용할 도구를 직접 선택할 수 있으며, 이로 인해 리액트로 만들어진 프로젝트는 매우 다양한 형태를 띤다. 이는 유연성을 제공하지만, 동시에 아키텍처 설계에 대한 책임도 개발자에게 주어진다는 의미이다.
2. SPA (Single Page Application)
리액트는 SPA(Single Page Application) 개발에 최적화된 라이브러리이다. SPA는 단일 HTML 페이지 위에서 동작하는 애플리케이션을 의미한다.
최초에 한 번만 전체 페이지를 로드하고, 이후에는 데이터가 변경될 때마다 서버로부터 필요한 데이터(주로 JSON 형태)만 비동기적으로 받아와 화면의 특정 부분만 동적으로 업데이트한다. 이는 전통적인 MPA(Multi Page Application)가 새로운 페이지로 이동할 때마다 서버로부터 전체 HTML을 새로 받아와 화면 전체를 다시 렌더링하는 것과 대조된다.
이러한 방식은 불필요한 렌더링을 최소화하여 애플리케이션의 반응 속도를 높이고, 사용자에게 마치 데스크톱 앱을 사용하는 듯한 부드럽고 쾌적한 사용자 경험(UX)을 제공한다.
3. 동작 원리: 가상돔 (Virtual DOM)
리액트의 효율적인 렌더링 성능의 핵심에는 가상돔(Virtual DOM)이 있다. 동작 과정은 다음과 같다.
- 초기 렌더링 (Initial Render)
- 애플리케이션이 처음 로드될 때, 리액트는 컴포넌트 구조를 기반으로 실제 DOM과 동일한 구조의 자바스크립트 객체인 가상돔을 메모리에 생성하고, 이를 실제 DOM으로 렌더링하여 화면에 표시한다.
- 가상돔 변경 (Virtual DOM Update)
- 사용자 인터랙션 등으로 인해 컴포넌트의 상태(State)가 변경되면, 리액트는 전체 UI를 실제 DOM에 바로 적용하지 않는다. 대신, 변경된 상태를 기반으로 새로운 가상돔 트리를 메모리에 생성한다.
- 재조정 (Reconciliation)
- 리액트는 이전 가상돔과 새로 생성된 가상돔을 비교하여 정확히 어떤 부분이 변경되었는지 찾아낸다. 이 비교 과정을 재조정(Reconciliation)이라고 하며, 리액트의 Diffing 알고리즘을 통해 효율적으로 수행된다.
- 실제 DOM 업데이트 (DOM Update)
- 리액트는 재조정 과정을 통해 파악된 실제 변경 사항만을 실제 DOM에 한 번에 적용(Batch Update)한다. 이는 불필요하고 비용이 많이 드는 DOM 조작을 최소화하여 성능을 최적화하는 핵심 원리이다.
4. JSX 문법
JSX(JavaScript XML)는 JavaScript를 확장한 문법으로, UI가 어떻게 생겨야 하는지를 시각적으로 표현할 수 있게 해준다.
- 하나의 컴포넌트는 반드시 하나의 최상위 태그로 감싸져야 한다. 불필요한
<div>사용을 피하고 싶을 경우, 빈 태그인 Fragment(<>...</>)를 사용할 수 있다. - JSX 내부에서 자바스크립트 표현식을 사용하려면 중괄호(
{})를 사용한다. - 조건부 렌더링을 위해 삼항 연산자나 논리 연산자(
&&,||)를 효과적으로 활용할 수 있다.
JSX 문법 예시 코드
import React from 'react';
function JsxSyntaxExample() {
const isLoggedIn = true;
const username = 'JHParrrk';
const items = ['Apple', 'Banana', 'Cherry'];
const unreadMessages = 5;
// 1. 최상위 요소로 Fragment 사용
return (
<>
{/* 2. 삼항 연산자를 이용한 조건부 렌더링 */}
<h1>{isLoggedIn ? `Welcome, ${username}!` : 'Please log in.'}</h1>
{/* 3. '&&' 연산자를 이용한 조건부 렌더링 */}
{unreadMessages > 0 && (
<h2>You have {unreadMessages} unread messages.</h2>
)}
{/* 4. '||' 연산자를 이용한 기본값 설정 */}
<p>Your nickname: {username || 'Guest'}</p>
{/* 5. map() 함수를 이용한 배열 렌더링 (key 속성 필수) */}
<h3>My Favorite Fruits</h3>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</>
);
}
export default JsxSyntaxExample;'Programmers' 카테고리의 다른 글
| [46일차]리액트(React)의 Props에 대하여 (0) | 2025.11.14 |
|---|---|
| [45일차]리액트(React) 컴포넌트와 상태 관리. (0) | 2025.11.13 |
| [43일차]타입스크립트 2일차: 타입과 객체 지향 프로그래밍의 통합. (0) | 2025.11.11 |
| [42일차]타입스크립트: 언어 개념과 기본 설정. (0) | 2025.11.10 |
| [과제] Book Market 프로젝트 결과 보고서 (0) | 2025.11.06 |