React의 핵심 원리와 사용 이유
React는 가상 문서 객체 모델(기존의 실제 DOM 대신)을 활용하여 렌더링 성능을 최적화합니다. 컴포넌트 상태가 변경되면, React는 새로운 가상 DOM 트리를 생성하고 기존 트리와 비교하여 차이를 분석하는 '차이 알고리즘'(Diff Algorithm)을 적용합니다. 이 과정을 통해 변동된 부분만 실제 DOM에 반영되므로, 불필요한 렌더링 작업을 줄이고 애플리케이션의 반응 속도를 향상시킵니다.
graph TD
A[div: App] --> B[h1: 제목]
A --> C[div: 콘텐츠]
C --> D[p: 안녕하세요, 세계!]
C --> E[button: 클릭해보세요]
CDN을 통한 간편 설정
빌드 도구 없이 바로 사용하려면, unpkg.com 또는 jsdeliver.net 같은 CDN을 통해 React와 ReactDOM을 직접 로드할 수 있습니다. 또한 JSX 문법은 브라우저에서 직접 해석되지 않으므로, Babel를 함께 포함해야 합니다.
<!-- React 및 ReactDOM 개발용 버전 -->
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js"></script>
<!-- JSX를 지원하는 런타임 컴파일러 -->
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone/babel.min.js"></script>
이후 <script type="text/babel"> 태그 내부에서 함수형 컴포넌트를 정의하고 렌더링합니다.
<script type="text/babel">
function Welcome() {
return <h1>반갑습니다, React!</h1>;
}
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<Welcome />);
</script>
| 항목 | 주소 | 목적 |
|---|---|---|
| React 핵심 | https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js |
컴포넌트 정의 및 관리 |
| ReactDOM | https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js |
UI 렌더링 |
| Babel | https://cdn.jsdelivr.net/npm/@babel/standalone/babel.min.js |
JSX 구문 변환 |
⚠️ 주의:
file://프로토콜에서는 네트워크 요청이 차단되므로, 실시간 미리보기를 위해 Live Server 확장 등 서버 환경을 사용해야 합니다.
NPM 기반 프로젝트 생성
프로젝트 초기화에는 Node.js 16 이상이 필요합니다.
npm -v
Vite를 이용해 프로젝트를 생성합니다.
npm create vite@latest
# 또는 특정 버전 지정: npm create vite@4.1.0
프로젝트 이름과 프레임워크 선택 후, 의존성 설치:
cd my-react-app
npm install
개발 서버 실행:
npm run dev
기본적으로 http://localhost:5173 에서 접근 가능합니다.
빌드 시:
npm run build
결과물은 build/ 폴더에 생성됩니다.
기본 프로젝트 구조
생성된 프로젝트에는 다음과 같은 파일과 폴더가 포함됩니다.
node_modules: 외부 라이브러리 저장소 (.gitignore에 포함 권고)public: 이미지, 아이콘 등의 정적 자원src: 소스 코드App.tsx: 기본 루트 컴포넌트index.css,App.css: 스타일 파일index.html: 애플리케이션 진입점package.json: 프로젝트 설정 및 패키지 정보
✅ 참고:
.js,.jsx,.ts,.tsx파일은 각각 일반 자바스크립트, JSX, 타입스크립트, 타입스크립트 + JSX를 의미합니다.
함수형 컴포넌트 만들기
컴포넌트는 재사용 가능한 UI 조각입니다. 현재는 함수형 방식이 표준입니다.
src/Message.tsx 파일 생성:
function Message() {
const userName = "Cacciatore";
return <h1>안녕하세요, {userName}님!</h1>;
}
export default Message;
이 코드는 실제 JSX이며, 내부적으로 React.createElement() 형태로 변환됩니다. 이를 확인하려면 Babel REPL을 사용하면 됩니다.
/*#__PURE__*/_jsx("h1", {
children: "안녕하세요, Cacciatore님!"
});
컴포넌트는 반드시 대문자로 시작해야 하며, 일반 HTML 태그와 구분됩니다.
App.tsx에서 메시지 컴포넌트 사용:
import Message from './Message';
function App() {
return (
<div>
<Message />
</div>
);
}
export default App;
스타일링 적용
예를 들어 부트스트랩을 사용하려면:
npm install bootstrap
main.tsx에서 스타일 임포트:
import 'bootstrap/dist/css/bootstrap.css';
import App from './App.tsx';
// ... 나머지 코드
새로운 컴포넌트 ListGroup.tsx 생성:
function ListGroup() {
const cities = ["뉴욕", "로스앤젤레스", "시카고", "휴스턴", "피닉스"];
return (
<>
<h2>도시 목록</h2>
{cities.map((city) => ( - {city}
))}
</>
);
}
export default ListGroup;
🔧 VSCode 사용 시,
Ctrl+Shift+I로 자동 정렬하거나Prettier플러그인 설치 추천. ⚠️class는 자바스크립트 예약어이므로, 클래스명은className으로 사용해야 함.
다중 요소 반환: 프래그먼트 사용
함수는 단일 루트 노드만 반환할 수 있습니다. 여러 요소를 반환해야 할 경우, Fragment를 사용하거나 비어 있는 태그(<>...</>)로 감싸면 됩니다.
import { Fragment } from 'react';
function ListGroup() {
return (
<Fragment>
<h2>도시 목록</h2>
{\['서울', '부산', '대구'\].map((city) => ( - {city}
))}
</Fragment>
);
}
또는 더 간결하게:
<>
<h2>도시 목록</h2>
{\['서울', '부산', '대구'\].map((city) => ( - {city}
))}
</>
동적 렌더링 표현
조건부 출력이나 반복 처리는 중괄호 {} 내부에서 처리합니다.
function ListGroup() {
const cities = [];
return (
<>
<h2>도시 목록</h2>
{cities.length === 0 ? (
<p className="text-muted">도시가 없습니다.</p>
) : null}
{cities.map((city) => ( - {city}
))}
</>
);
}
또는 단순한 조건 연산자 사용:
cities.length === 0 && <p>도시 없음</p>
이 식은 조건이 참일 때만 <p> 요소를 렌더링합니다.