React
개요
React(리액트)는 페이스북(Facebook) 이 2013년에 오픈소스로 공개한 자바스크립트 기반 UI(User Interface) 라이브러리이다. 단일 페이지 애플리케이션(SPA)이나 복잡한 사용자 인터페이스를 컴포넌트 기반으로 선언적으로 구축할 수 있게 해준다. 가상 DOM(Virtual DOM)이라는 효율적인 렌더링 메커니즘을 통해 UI 업데이트 성능을 최적화하고, Hooks(훅)와 Context API 등 최신 기능을 제공한다. 현재는 웹뿐 아니라 React Native(모바일), React VR(가상현실) 등 다양한 플랫폼에서도 활용된다.
목차
- 역사와 배경
- 핵심 개념
- 컴포넌트
- JSX
- Props와 State
- 생명주기(Lifecycle)
- Hooks
- React 생태계
- 라우팅(Router)
- 상태 관리(State Management)
- 빌드 도구와 테스트
- 성능 최적화
- 베스트 프랙티스
- 비교·대안
- 참고 자료
역사와 배경
| 연도 |
주요 사건 |
| 2011 |
페이스북 내부 프로젝트 “FaxJS”로 시작 |
| 2013 |
오픈소스 공개 (BSD-3-Clause 라이선스) |
| 2015 |
React 0.14 출시 – Component와 DOM 분리 |
| 2017 |
React Fiber(새로운 내부 알고리즘) 도입 |
| 2018 |
Hooks(useState, useEffect 등) 정식 추가 |
| 2020~ |
Concurrent Mode, Suspense 등 점진적 기능 확대 |
React는 컴포넌트 재사용성과 선언적 UI를 강조함으로써 기존 jQuery 기반 개발 방식의 복잡성을 크게 낮췄다.
핵심 개념
컴포넌트
React 애플리케이션은 컴포넌트라는 독립적인 단위로 구성된다. 컴포넌트는 함수형(Function Component) 또는 클래스형(Class Component)으로 정의할 수 있다.
// 함수형 컴포넌트 예시
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// 클래스형 컴포넌트 예시
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <button>{this.state.count}</button>;
}
}
컴포넌트: UI를 구성하는 재사용 가능한 블록. 입력값(Props)과 내부 상태(State)를 기반으로 렌더링 결과를 반환한다.
JSX
JSX(JavaScript XML)는 자바스크립트 안에 HTML‑like 문법을 삽입할 수 있게 해주는 문법 확장이다. Babel 같은 트랜스파일러가 JSX를 React.createElement 호출로 변환한다.
const element = <div className="box">Hello</div>;
트랜스파일러: 최신 문법을 구형 브라우저가 이해할 수 있는 코드로 변환해 주는 도구.
Props와 State
- Props(Properties): 부모 컴포넌트가 자식에게 전달하는 읽기 전용 데이터. 변경이 필요하면 부모가 다시 전달한다.
- State: 컴포넌트 내부에서 변경 가능한 데이터.
setState(클래스) 혹은 useState(함수)로 업데이트한다.
function Counter() {
const [count, setCount] = useState(0); // state 선언
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
생명주기(Lifecycle)
클래스형 컴포넌트는 생명주기 메서드를 통해 마운트·업데이트·언마운트 시점에 로직을 삽입한다.
| 단계 |
메서드 (클래스) |
설명 |
| 마운트 |
constructor, componentDidMount |
초기화 및 DOM 삽입 후 실행 |
| 업데이트 |
shouldComponentUpdate, componentDidUpdate |
리렌더링 전·후에 호출 |
| 언마운트 |
componentWillUnmount |
정리 작업 수행 |
함수형 컴포넌트에서는 Hooks(useEffect 등)로 동일한 동작을 구현한다.
Hooks
React 16.8부터 도입된 Hooks는 함수형 컴포넌트에서도 상태 관리와 부수 효과( side‑effect )를 사용할 수 있게 해준다. 주요 Hook은 다음과 같다.
| Hook |
목적 |
사용 예시 |
useState |
로컬 state 선언 |
const [value, setValue] = useState(initial); |
useEffect |
부수 효과(데이터 fetch, 구독 등) |
useEffect(() => { fetchData(); }, [deps]); |
useContext |
Context API 접근 |
const theme = useContext(ThemeContext); |
useMemo |
연산 결과 메모이제이션 |
const memoized = useMemo(() => compute(a,b), [a,b]); |
useCallback |
콜백 함수 메모이제이션 |
const handler = useCallback(() => doSomething(), [dep]); |
useReducer |
복잡한 state 로직 |
const [state, dispatch] = useReducer(reducer, init); |
부수 효과: 컴포넌트 렌더링 외에 수행되는 작업(네트워크 요청, 타이머 설정 등).
Custom Hook
재사용 가능한 로직을 함수 형태로 캡슐화한 것이 Custom Hook이다.
function useWindowSize() {
const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
useEffect(() => {
const onResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}, []);
return size;
}
React 생태계
라우팅(Router)
SPA에서 페이지 전환을 담당하는 라이브러리다. 가장 널리 쓰이는 React Router는 선언형 라우팅을 제공한다.
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
상태 관리(State Management)
컴포넌트 트리 전반에 걸친 복잡한 상태를 관리하기 위한 도구들.
| 도구 |
특징 |
| Redux |
전역 상태를 스토어(Store)에 저장, dispatch와 reducer 사용 |
| MobX |
관찰 가능한(observable) 데이터와 자동 추적 기반 |
| Recoil |
React 내부 API와 동일한 방식으로 atom, selector 제공 |
| Context API |
간단한 전역값 전달에 적합, 별도 라이브러리 불필요 |
빌드 도구와 테스트
- Create React App(CRA): 설정이 사전 구성된 프로젝트 템플릿. Webpack, Babel, ESLint 등 기본 제공.
- Next.js: 서버 사이드 렌더링(SSR) 및 정적 사이트 생성(SSG) 지원.
- Testing Library: 사용자 관점 테스트를 위한
@testing-library/react.
- Jest: 단위·통합 테스트 프레임워크.
성능 최적화
- 불필요한 렌더링 방지
React.memo(함수형) 혹은 PureComponent(클래스) 사용.
-
useCallback·useMemo로 props 전달 시 동일 객체 유지.
-
코드 스플리팅(Code Splitting)
React.lazy와 Suspense로 라우트 별 청크(chunk) 로드.
const Dashboard = React.lazy(() => import('./Dashboard'));
<Suspense fallback={<Spinner />}>
<Dashboard />
</Suspense>
- Virtualized List
-
대량 데이터 리스트는 react-window·react-virtualized 사용.
-
이미지·미디어 최적화
-
srcset, lazy-loading 속성 활용.
-
Concurrent Mode & Suspense(실험적)
- 비동기 UI를 미리 준비해 UI 차단을 최소화.
베스트 프랙티스
| 분야 |
권장 사항 |
| 컴포넌트 설계 |
한 컴포넌트는 단일 책임 원칙을 따르고, 재사용성을 고려해 작은 단위로 분리 |
| 스타일링 |
CSS‑in‑JS(styled-components, emotion) 혹은 CSS Modules 사용으로 전역 스타일 충돌 방지 |
| 타입 |
TypeScript와 함께 사용해 정적 타입 검사 적용 |
| 테스트 |
UI 테스트는 Testing Library, 로직 테스트는 Jest 활용 |
| 접근성 |
aria-* 속성, 키보드 내비게이션, 색 대비 등 WCAG 가이드 준수 |
| 버전 관리 |
React 18 이상을 사용하고, React.StrictMode로 잠재적 문제 탐지 |
비교·대안
| 라이브러리/프레임워크 |
주요 특징 |
사용 사례 |
| Vue.js |
옵션 기반 API와 템플릿 문법, 가벼운 러닝 커브 |
소규모 프로젝트, 빠른 프로토타이핑 |
| Angular |
완전한 프레임워크, TypeScript 기반, DI(Dependency Injection) 제공 |
대규모 엔터프라이즈 애플리케이션 |
| Svelte |
컴파일 단계에서 DOM 업데이트 코드를 생성, 런타임 오버헤드 최소 |
퍼포먼스가 중요한 UI |
| Preact |
React와 동일 API, 파일 크기 3KB 이하 |
모바일/IoT 등 제한된 리소스 환경 |
React는 생태계가 가장 풍부하고, 기업 채택률이 높아 인재 확보와 커뮤니티 지원 면에서 강점이 있다.
참고 자료
이 문서는 2024년 기준 최신 정보를 반영하였으며, React의 버전 업그레이드에 따라 일부 내용이 변동될 수 있다.
# React
## 개요
React(리액트)는 **페이스북(Facebook)** 이 2013년에 오픈소스로 공개한 **자바스크립트 기반 UI(User Interface) 라이브러리**이다. 단일 페이지 애플리케이션(SPA)이나 복잡한 사용자 인터페이스를 **컴포넌트 기반**으로 선언적으로 구축할 수 있게 해준다. 가상 DOM(Virtual DOM)이라는 효율적인 렌더링 메커니즘을 통해 UI 업데이트 성능을 최적화하고, **Hooks**(훅)와 **Context API** 등 최신 기능을 제공한다. 현재는 웹뿐 아니라 **React Native**(모바일), **React VR**(가상현실) 등 다양한 플랫폼에서도 활용된다.
---
## 목차
1. [역사와 배경](#역사와-배경)
2. [핵심 개념](#핵심-개념)
- [컴포넌트](#컴포넌트)
- [JSX](#jsx)
- [Props와 State](#props와-state)
- [생명주기(Lifecycle)](#생명주기)
3. [Hooks](#hooks)
4. [React 생태계](#react-생태계)
- [라우팅(Router)](#라우팅)
- 상태 관리(State Management)
- 빌드 도구와 테스트
5. [성능 최적화](#성능-최적화)
6. [베스트 프랙티스](#베스트-프랙티스)
7. [비교·대안](#비교대안)
8. [참고 자료](#참고-자료)
---
## 역사와 배경
| 연도 | 주요 사건 |
|------|-----------|
| 2011 | 페이스북 내부 프로젝트 “FaxJS”로 시작 |
| 2013 | 오픈소스 공개 (BSD-3-Clause 라이선스) |
| 2015 | React 0.14 출시 – **Component**와 **DOM** 분리 |
| 2017 | **React Fiber**(새로운 내부 알고리즘) 도입 |
| 2018 | **Hooks**(useState, useEffect 등) 정식 추가 |
| 2020~ | Concurrent Mode, Suspense 등 점진적 기능 확대 |
React는 **컴포넌트 재사용성**과 **선언적 UI**를 강조함으로써 기존 jQuery 기반 개발 방식의 복잡성을 크게 낮췄다.
---
## 핵심 개념
### 컴포넌트
React 애플리케이션은 **컴포넌트**라는 독립적인 단위로 구성된다. 컴포넌트는 **함수형**(Function Component) 또는 **클래스형**(Class Component)으로 정의할 수 있다.
```jsx
// 함수형 컴포넌트 예시
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// 클래스형 컴포넌트 예시
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <button>{this.state.count}</button>;
}
}
```
> **컴포넌트**: UI를 구성하는 재사용 가능한 블록. 입력값(Props)과 내부 상태(State)를 기반으로 렌더링 결과를 반환한다.
### JSX
**JSX**(JavaScript XML)는 자바스크립트 안에 HTML‑like 문법을 삽입할 수 있게 해주는 **문법 확장**이다. Babel 같은 트랜스파일러가 JSX를 `React.createElement` 호출로 변환한다.
```jsx
const element = <div className="box">Hello</div>;
```
> **트랜스파일러**: 최신 문법을 구형 브라우저가 이해할 수 있는 코드로 변환해 주는 도구.
### Props와 State
- **Props**(Properties): 부모 컴포넌트가 자식에게 전달하는 **읽기 전용 데이터**. 변경이 필요하면 부모가 다시 전달한다.
- **State**: 컴포넌트 내부에서 **변경 가능한 데이터**. `setState`(클래스) 혹은 `useState`(함수)로 업데이트한다.
```jsx
function Counter() {
const [count, setCount] = useState(0); // state 선언
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
```
### 생명주기(Lifecycle)
클래스형 컴포넌트는 **생명주기 메서드**를 통해 마운트·업데이트·언마운트 시점에 로직을 삽입한다.
| 단계 | 메서드 (클래스) | 설명 |
|------|----------------|------|
| 마운트 | `constructor`, `componentDidMount` | 초기화 및 DOM 삽입 후 실행 |
| 업데이트 | `shouldComponentUpdate`, `componentDidUpdate` | 리렌더링 전·후에 호출 |
| 언마운트 | `componentWillUnmount` | 정리 작업 수행 |
함수형 컴포넌트에서는 **Hooks**(`useEffect` 등)로 동일한 동작을 구현한다.
---
## Hooks
React 16.8부터 도입된 Hooks는 **함수형 컴포넌트**에서도 상태 관리와 부수 효과( side‑effect )를 사용할 수 있게 해준다. 주요 Hook은 다음과 같다.
| Hook | 목적 | 사용 예시 |
|------|------|-----------|
| `useState` | 로컬 state 선언 | `const [value, setValue] = useState(initial);` |
| `useEffect` | 부수 효과(데이터 fetch, 구독 등) | `useEffect(() => { fetchData(); }, [deps]);` |
| `useContext` | Context API 접근 | `const theme = useContext(ThemeContext);` |
| `useMemo` | 연산 결과 메모이제이션 | `const memoized = useMemo(() => compute(a,b), [a,b]);` |
| `useCallback` | 콜백 함수 메모이제이션 | `const handler = useCallback(() => doSomething(), [dep]);` |
| `useReducer` | 복잡한 state 로직 | `const [state, dispatch] = useReducer(reducer, init);` |
> **부수 효과**: 컴포넌트 렌더링 외에 수행되는 작업(네트워크 요청, 타이머 설정 등).
### Custom Hook
재사용 가능한 로직을 **함수** 형태로 캡슐화한 것이 **Custom Hook**이다.
```jsx
function useWindowSize() {
const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
useEffect(() => {
const onResize = () => setSize({ width: window.innerWidth, height: window.innerHeight });
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}, []);
return size;
}
```
---
## React 생태계
### 라우팅(Router)
SPA에서 페이지 전환을 담당하는 라이브러리다. 가장 널리 쓰이는 **React Router**는 선언형 라우팅을 제공한다.
```jsx
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
```
### 상태 관리(State Management)
컴포넌트 트리 전반에 걸친 복잡한 상태를 관리하기 위한 도구들.
| 도구 | 특징 |
|------|------|
| **Redux** | 전역 상태를 **스토어(Store)**에 저장, `dispatch`와 `reducer` 사용 |
| **MobX** | 관찰 가능한(observable) 데이터와 자동 추적 기반 |
| **Recoil** | React 내부 API와 동일한 방식으로 atom, selector 제공 |
| **Context API** | 간단한 전역값 전달에 적합, 별도 라이브러리 불필요 |
### 빌드 도구와 테스트
- **Create React App(CRA)**: 설정이 사전 구성된 프로젝트 템플릿. Webpack, Babel, ESLint 등 기본 제공.
- **Next.js**: 서버 사이드 렌더링(SSR) 및 정적 사이트 생성(SSG) 지원.
- **Testing Library**: 사용자 관점 테스트를 위한 `@testing-library/react`.
- **Jest**: 단위·통합 테스트 프레임워크.
---
## 성능 최적화
1. **불필요한 렌더링 방지**
- `React.memo`(함수형) 혹은 `PureComponent`(클래스) 사용.
- `useCallback`·`useMemo`로 props 전달 시 동일 객체 유지.
2. **코드 스플리팅(Code Splitting)**
- `React.lazy`와 `Suspense`로 라우트 별 청크(chunk) 로드.
```jsx
const Dashboard = React.lazy(() => import('./Dashboard'));
<Suspense fallback={<Spinner />}>
<Dashboard />
</Suspense>
```
3. **Virtualized List**
- 대량 데이터 리스트는 `react-window`·`react-virtualized` 사용.
4. **이미지·미디어 최적화**
- `srcset`, `lazy-loading` 속성 활용.
5. **Concurrent Mode & Suspense**(실험적)
- 비동기 UI를 미리 준비해 UI 차단을 최소화.
---
## 베스트 프랙티스
| 분야 | 권장 사항 |
|------|-----------|
| **컴포넌트 설계** | 한 컴포넌트는 **단일 책임** 원칙을 따르고, 재사용성을 고려해 작은 단위로 분리 |
| **스타일링** | CSS‑in‑JS(`styled-components`, `emotion`) 혹은 **CSS Modules** 사용으로 전역 스타일 충돌 방지 |
| **타입** | TypeScript와 함께 사용해 **정적 타입 검사** 적용 |
| **테스트** | UI 테스트는 **Testing Library**, 로직 테스트는 **Jest** 활용 |
| **접근성** | `aria-*` 속성, 키보드 내비게이션, 색 대비 등 **WCAG** 가이드 준수 |
| **버전 관리** | React 18 이상을 사용하고, **React.StrictMode**로 잠재적 문제 탐지 |
---
## 비교·대안
| 라이브러리/프레임워크 | 주요 특징 | 사용 사례 |
|-----------------------|----------|-----------|
| **Vue.js** | 옵션 기반 API와 템플릿 문법, 가벼운 러닝 커브 | 소규모 프로젝트, 빠른 프로토타이핑 |
| **Angular** | 완전한 프레임워크, TypeScript 기반, DI(Dependency Injection) 제공 | 대규모 엔터프라이즈 애플리케이션 |
| **Svelte** | 컴파일 단계에서 DOM 업데이트 코드를 생성, 런타임 오버헤드 최소 | 퍼포먼스가 중요한 UI |
| **Preact** | React와 동일 API, 파일 크기 3KB 이하 | 모바일/IoT 등 제한된 리소스 환경 |
React는 **생태계가 가장 풍부**하고, **기업 채택률**이 높아 인재 확보와 커뮤니티 지원 면에서 강점이 있다.
---
## 참고 자료
- 공식 문서: <https://reactjs.org/>
- React 공식 블로그: <https://reactjs.org/blog/>
- React Router Docs: <https://reactrouter.com/>
- Redux Toolkit: <https://redux-toolkit.js.org/>
- Dan Abramov, “The History of React” (2020) – React 창시자 인터뷰
- “Fullstack React” (O'Reilly, 2021) – 실전 프로젝트 예제
---
*이 문서는 2024년 기준 최신 정보를 반영하였으며, React의 버전 업그레이드에 따라 일부 내용이 변동될 수 있다.*