React
개요
React(리액트)는 페이스북(현 메타)에서 2013년에 공개한 오픈소스 UI 라이브러리이다. 선언적인 방식으로 사용자 인터페이스(UI)를 구성하고, 컴포넌트 기반 구조를 통해 재사용성을 극대화한다. React는 가상 DOM(Virtual DOM) 을 활용해 실제 DOM 업데이트를 최소화함으로써 높은 성능을 제공한다. 현재 웹·모바일·데스크톱(React Native, Electron 등) 전반에 걸쳐 광범위하게 사용되고 있다.
주요 특징
| 특징 |
설명 |
활용 예시 |
| 선언적 UI |
UI 상태를 선언적으로 기술하면, 상태 변화에 따라 React가 자동으로 UI를 갱신한다. |
state가 바뀔 때마다 render 함수를 직접 호출할 필요 없음 |
| 컴포넌트 기반 |
UI를 컴포넌트라는 독립적인 단위로 나누어 관리한다. |
버튼, 폼, 리스트 등 각각을 별도 파일·함수로 구현 |
| 가상 DOM |
실제 DOM과 동일한 구조를 메모리 상에 유지하고, 차이점(diff)만 실제 DOM에 적용한다. |
대규모 리스트 렌더링 시 성능 저하 최소화 |
| 단방향 데이터 흐름 |
데이터는 부모 → 자식 방향으로만 흐르며, 변경은 콜백을 통해 상위로 전달한다. |
props와 setState를 이용한 상태 관리 |
핵심 개념
1. 컴포넌트
React 컴포넌트는 함수형과 클래스형 두 가지 방식으로 정의할 수 있다. 현재는 함수형 컴포넌트와 Hook(훅) 사용이 권장된다.
| 구분 |
선언 방식 |
주요 특징 |
| 함수형 |
function MyComponent() { … } |
가볍고, Hook을 통해 상태·생명주기 관리 |
| 클래스형 |
class MyComponent extends React.Component { … } |
this.state, componentDidMount 등 메서드 사용 (레거시) |
Hook은 함수형 컴포넌트에서 상태·부수 효과·컨텍스트 등을 활용하게 해 주는 API이다.
2. JSX
JSX는 JavaScript XML의 약자로, JavaScript 안에 HTML‑like 문법을 직접 쓸 수 있게 해준다. Babel 등 트랜스파일러가 React.createElement 호출로 변환한다.
const greeting = <h1>Hello, {userName}!</h1>;
주의: JSX는 반드시 하나의 최상위 요소로 감싸야 한다. 여러 요소가 필요하면 <React.Fragment> 혹은 <>...를 사용한다.
3. State와 Props
| 용어 |
설명 |
변경 가능 여부 |
| State |
컴포넌트 내부에서 관리되는 데이터. UI에 직접적인 영향을 미친다. |
가능 (setState / useState) |
| Props |
부모 컴포넌트가 자식에게 전달하는 읽기 전용 데이터. |
불가능 (읽기 전용) |
function Counter() {
const [count, setCount] = useState(0); // state 선언
return (
<button onClick={() => setCount(count + 1)}>
클릭 횟수: {count}
</button>
);
}
4. Hook
| Hook |
용도 |
기본 사용법 |
useState |
로컬 상태 관리 |
const [value, setValue] = useState(initial); |
useEffect |
부수 효과(데이터 fetch, 구독 등) |
useEffect(() => { … }, [deps]); |
useContext |
전역 컨텍스트 접근 |
const ctx = useContext(MyContext); |
useMemo |
연산 결과 메모이제이션 |
const memo = useMemo(() => compute(a,b), [a,b]); |
useCallback |
콜백 함수 메모이제이션 |
const cb = useCallback(() => doSomething(), [dep]); |
| Custom Hook |
재사용 가능한 로직 캡슐화 |
function useFetch(url) { … } |
5. 라우팅 (React Router)
단일 페이지 애플리케이션(SPA)에서 URL 기반 페이지 전환을 담당한다.
import { BrowserRouter, Routes, Route } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
6. 상태 관리
| 라이브러리 |
특징 |
사용 시점 |
| Redux |
전역 상태를 스토어에 저장, 액션·리듀서 패턴 |
복잡한 상태 흐름, 대규모 앱 |
| MobX |
관찰 가능한(state) 객체와 자동 반응 |
직관적인 반응형 프로그래밍 |
| Context API |
React 자체 제공, 간단한 전역 상태 |
테마, 인증 정보 등 소규모 공유 |
| Recoil |
Atom·Selector 기반, React와 친화적 |
최신 프로젝트, 실험적 도입 |
개발 환경 설정
- Node.js와 npm(또는 yarn) 설치
- 프로젝트 초기화
- Create React App(CRA)
npx create-react-app my-app
cd my-app
npm start
- Vite(경량·빠른 빌드)
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
- ESLint, Prettier 등 코드 품질 도구 연동
- React DevTools(Chrome/Firefox 확장) 설치 → 컴포넌트 트리·state 확인 가능
성능 최적화 기법
| 기법 |
설명 |
적용 예시 |
| React.memo |
props가 변하지 않으면 재렌더링 방지 (함수형 컴포넌트) |
export default React.memo(MyComponent); |
| useMemo / useCallback |
복잡 연산·함수 재생성을 메모이제이션 |
const memoized = useMemo(() => heavyCalc(a), [a]); |
| 코드 스플리팅 |
라우트·컴포넌트 단위로 번들 분리 |
const LazyComp = React.lazy(() => import('./LazyComp')); |
| Suspense |
비동기 로딩 UI 제공 |
<Suspense fallback={<Spinner/>}> <LazyComp/> </Suspense> |
| 키 최적화 |
리스트 렌더링 시 고유 key 사용 |
<li key={item.id}> |
| SSR (Server‑Side Rendering) |
초기 HTML을 서버에서 미리 렌더링 → SEO·첫 화면 속도 개선 |
Next.js, Remix 등 사용 |
배포와 빌드
npm run build # production용 정적 파일 생성 (dist/ 폴더)
- 정적 호스팅: Netlify, Vercel, GitHub Pages 등
- SSR/SSG: Next.js(서버 사이드 렌더링) 혹은 Gatsby(정적 사이트 생성) 활용 가능
- Docker:
Dockerfile에 node:alpine 기반 이미지로 빌드 후 Nginx에 서빙
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
관련 도구 및 라이브러리
| 도구 |
용도 |
| React DevTools |
컴포넌트 트리·state·props 실시간 확인 |
| Storybook |
UI 컴포넌트 독립 개발·문서화 |
| Testing Library + Jest |
사용자 관점 테스트(렌더링·이벤트) |
| ESLint-plugin-react |
React 전용 린팅 규칙 |
| styled-components, Emotion |
CSS‑in‑JS 스타일링 |
| React Query |
서버 상태(fetch·cache·sync) 관리 |
| React Hook Form |
폼 유효성 검사·제출 로직 간소화 |
참고 자료
| 번호 |
출처 |
내용 |
| 1 |
React 공식 문서 |
기본 개념·API·베스트 프랙티스 |
| 2 |
Dan Abramov, “The Road to React” |
초·중급 학습서 |
| 3 |
Kent C. Dodds, “Testing JavaScript Applications” |
React 테스트 전략 |
| 4 |
Vite 공식 사이트 |
최신 빌드 툴 사용법 |
| 5 |
Next.js Documentation |
SSR·SSG 활용 가이드 |
| 6 |
“React 디자인 패턴” (한빛미디어) |
실무 적용 패턴 정리 |
요약
React는 선언적 UI와 가상 DOM을 기반으로 컴포넌트 단위의 재사용성을 강조한다. 함수형 컴포넌트와 Hook을 중심으로 현대적인 개발 흐름을 제공하며, React Router, Redux, Context API 등과 결합해 복잡한 SPA를 효율적으로 구축한다. 성능 최적화와 배포 전략을 적절히 적용하면, 규모와 요구사항에 관계없이 안정적인 웹 애플리케이션을 만들 수 있다.
# React
## 개요
**React**(리액트)는 페이스북(현 메타)에서 2013년에 공개한 **오픈소스 UI 라이브러리**이다. 선언적인 방식으로 사용자 인터페이스(UI)를 구성하고, **컴포넌트 기반** 구조를 통해 재사용성을 극대화한다. React는 **가상 DOM(Virtual DOM)** 을 활용해 실제 DOM 업데이트를 최소화함으로써 높은 성능을 제공한다. 현재 웹·모바일·데스크톱(React Native, Electron 등) 전반에 걸쳐 광범위하게 사용되고 있다.
---
## 주요 특징
| 특징 | 설명 | 활용 예시 |
|------|------|----------|
| **선언적 UI** | UI 상태를 선언적으로 기술하면, 상태 변화에 따라 React가 자동으로 UI를 갱신한다. | `state`가 바뀔 때마다 `render` 함수를 직접 호출할 필요 없음 |
| **컴포넌트 기반** | UI를 **컴포넌트**라는 독립적인 단위로 나누어 관리한다. | 버튼, 폼, 리스트 등 각각을 별도 파일·함수로 구현 |
| **가상 DOM** | 실제 DOM과 동일한 구조를 메모리 상에 유지하고, 차이점(diff)만 실제 DOM에 적용한다. | 대규모 리스트 렌더링 시 성능 저하 최소화 |
| **단방향 데이터 흐름** | 데이터는 부모 → 자식 방향으로만 흐르며, 변경은 콜백을 통해 상위로 전달한다. | `props`와 `setState`를 이용한 상태 관리 |
---
## 핵심 개념
### 1. 컴포넌트
React 컴포넌트는 **함수형**과 **클래스형** 두 가지 방식으로 정의할 수 있다. 현재는 **함수형 컴포넌트**와 **Hook**(훅) 사용이 권장된다.
| 구분 | 선언 방식 | 주요 특징 |
|------|----------|-----------|
| **함수형** | `function MyComponent() { … }` | 가볍고, Hook을 통해 상태·생명주기 관리 |
| **클래스형** | `class MyComponent extends React.Component { … }` | `this.state`, `componentDidMount` 등 메서드 사용 (레거시) |
> **Hook**은 함수형 컴포넌트에서 상태·부수 효과·컨텍스트 등을 활용하게 해 주는 API이다.
### 2. JSX
JSX는 **JavaScript XML**의 약자로, JavaScript 안에 HTML‑like 문법을 직접 쓸 수 있게 해준다. Babel 등 트랜스파일러가 `React.createElement` 호출로 변환한다.
```jsx
const greeting = <h1>Hello, {userName}!</h1>;
```
> **주의**: JSX는 반드시 하나의 최상위 요소로 감싸야 한다. 여러 요소가 필요하면 `<React.Fragment>` 혹은 `<>...</>`를 사용한다.
### 3. State와 Props
| 용어 | 설명 | 변경 가능 여부 |
|------|------|----------------|
| **State** | 컴포넌트 내부에서 관리되는 데이터. UI에 직접적인 영향을 미친다. | **가능** (`setState` / `useState`) |
| **Props** | 부모 컴포넌트가 자식에게 전달하는 읽기 전용 데이터. | **불가능** (읽기 전용) |
```jsx
function Counter() {
const [count, setCount] = useState(0); // state 선언
return (
<button onClick={() => setCount(count + 1)}>
클릭 횟수: {count}
</button>
);
}
```
### 4. Hook
| Hook | 용도 | 기본 사용법 |
|------|------|-------------|
| `useState` | 로컬 상태 관리 | `const [value, setValue] = useState(initial);` |
| `useEffect` | 부수 효과(데이터 fetch, 구독 등) | `useEffect(() => { … }, [deps]);` |
| `useContext` | 전역 컨텍스트 접근 | `const ctx = useContext(MyContext);` |
| `useMemo` | 연산 결과 메모이제이션 | `const memo = useMemo(() => compute(a,b), [a,b]);` |
| `useCallback` | 콜백 함수 메모이제이션 | `const cb = useCallback(() => doSomething(), [dep]);` |
| **Custom Hook** | 재사용 가능한 로직 캡슐화 | `function useFetch(url) { … }` |
### 5. 라우팅 (React Router)
단일 페이지 애플리케이션(SPA)에서 URL 기반 페이지 전환을 담당한다.
```jsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
```
### 6. 상태 관리
| 라이브러리 | 특징 | 사용 시점 |
|------------|------|-----------|
| **Redux** | 전역 상태를 **스토어**에 저장, 액션·리듀서 패턴 | 복잡한 상태 흐름, 대규모 앱 |
| **MobX** | 관찰 가능한(state) 객체와 자동 반응 | 직관적인 반응형 프로그래밍 |
| **Context API** | React 자체 제공, 간단한 전역 상태 | 테마, 인증 정보 등 소규모 공유 |
| **Recoil** | Atom·Selector 기반, React와 친화적 | 최신 프로젝트, 실험적 도입 |
---
## 개발 환경 설정
1. **Node.js**와 **npm**(또는 **yarn**) 설치
2. 프로젝트 초기화
- **Create React App(CRA)**
```bash
npx create-react-app my-app
cd my-app
npm start
```
- **Vite**(경량·빠른 빌드)
```bash
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
```
3. **ESLint**, **Prettier** 등 코드 품질 도구 연동
4. **React DevTools**(Chrome/Firefox 확장) 설치 → 컴포넌트 트리·state 확인 가능
---
## 성능 최적화 기법
| 기법 | 설명 | 적용 예시 |
|------|------|-----------|
| **React.memo** | props가 변하지 않으면 재렌더링 방지 (함수형 컴포넌트) | `export default React.memo(MyComponent);` |
| **useMemo / useCallback** | 복잡 연산·함수 재생성을 메모이제이션 | `const memoized = useMemo(() => heavyCalc(a), [a]);` |
| **코드 스플리팅** | 라우트·컴포넌트 단위로 번들 분리 | `const LazyComp = React.lazy(() => import('./LazyComp'));` |
| **Suspense** | 비동기 로딩 UI 제공 | `<Suspense fallback={<Spinner/>}> <LazyComp/> </Suspense>` |
| **키 최적화** | 리스트 렌더링 시 고유 `key` 사용 | `<li key={item.id}>` |
| **SSR (Server‑Side Rendering)** | 초기 HTML을 서버에서 미리 렌더링 → SEO·첫 화면 속도 개선 | Next.js, Remix 등 사용 |
---
## 배포와 빌드
```bash
npm run build # production용 정적 파일 생성 (dist/ 폴더)
```
* **정적 호스팅**: Netlify, Vercel, GitHub Pages 등
* **SSR/SSG**: Next.js(서버 사이드 렌더링) 혹은 Gatsby(정적 사이트 생성) 활용 가능
* **Docker**: `Dockerfile`에 `node:alpine` 기반 이미지로 빌드 후 Nginx에 서빙
```Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
---
## 관련 도구 및 라이브러리
| 도구 | 용도 |
|------|------|
| **React DevTools** | 컴포넌트 트리·state·props 실시간 확인 |
| **Storybook** | UI 컴포넌트 독립 개발·문서화 |
| **Testing Library** + **Jest** | 사용자 관점 테스트(렌더링·이벤트) |
| **ESLint-plugin-react** | React 전용 린팅 규칙 |
| **styled-components**, **Emotion** | CSS‑in‑JS 스타일링 |
| **React Query** | 서버 상태(fetch·cache·sync) 관리 |
| **React Hook Form** | 폼 유효성 검사·제출 로직 간소화 |
---
## 참고 자료
| 번호 | 출처 | 내용 |
|------|------|------|
| 1 | [React 공식 문서](https://reactjs.org) | 기본 개념·API·베스트 프랙티스 |
| 2 | Dan Abramov, *“The Road to React”* | 초·중급 학습서 |
| 3 | Kent C. Dodds, *“Testing JavaScript Applications”* | React 테스트 전략 |
| 4 | Vite 공식 사이트 | 최신 빌드 툴 사용법 |
| 5 | Next.js Documentation | SSR·SSG 활용 가이드 |
| 6 | “React 디자인 패턴” (한빛미디어) | 실무 적용 패턴 정리 |
---
> **요약**
> React는 선언적 UI와 가상 DOM을 기반으로 **컴포넌트** 단위의 재사용성을 강조한다. 함수형 컴포넌트와 **Hook**을 중심으로 현대적인 개발 흐름을 제공하며, **React Router**, **Redux**, **Context API** 등과 결합해 복잡한 SPA를 효율적으로 구축한다. 성능 최적화와 배포 전략을 적절히 적용하면, 규모와 요구사항에 관계없이 안정적인 웹 애플리케이션을 만들 수 있다.