함수 컴포넌트를 선언하고 조합하는 방법, 컴포넌트를 파일로 분리하는 패턴, 재사용의 본질적 의미를 코드로 배웁니다.
🧱 컴포넌트란 무엇인가 — 다시 한 번
리액트에서 컴포넌트는 UI의 독립적인 단위입니다. 기술적으로는 JSX를 반환하는 JavaScript 함수입니다. 단순하지만 이 개념 하나로 복잡한 UI를 구조적으로 만들 수 있습니다. 이번 강의에서는 컴포넌트를 직접 만들고, 조합하고, 파일로 분리하는 모든 과정을 배웁니다.
✍️ 함수 컴포넌트 선언
함수 컴포넌트는 JSX를 반환하는 일반 함수입니다. 두 가지 규칙만 기억하세요:
- 이름은 대문자로 시작해야 합니다. (
MyComponentO,myComponentX) - JSX를 반환해야 합니다 (또는 null).
// 가장 단순한 컴포넌트
function Greeting() {
return <h1>안녕하세요! 👋</h1>
}
// 화살표 함수 형태도 동일
const Greeting = () => {
return <h1>안녕하세요! 👋</h1>
}
// 한 줄이면 return 생략 가능
const Greeting = () => <h1>안녕하세요! 👋</h1>
세 가지 형태 모두 동작합니다. 팀의 컨벤션을 따르되, 일반 함수 선언문(function)이 현재 가장 일반적입니다.
🔗 컴포넌트 조합 — 큰 것을 작은 것으로
컴포넌트의 진짜 힘은 조합(Composition)에 있습니다. 작은 컴포넌트들을 레고처럼 조립해 복잡한 UI를 만듭니다.
// 작은 컴포넌트들
function Avatar() {
return <img src="/avatar.png" alt="프로필" className="w-10 h-10 rounded-full" />
}
function UserName() {
return <span className="font-bold">김민준</span>
}
function Badge() {
return <span className="bg-blue-100 text-blue-700 px-2 py-0.5 rounded text-xs">프리미엄</span>
}
// 조합해서 더 큰 컴포넌트 만들기
function UserCard() {
return (
<div className="flex items-center gap-3 p-4 border rounded-lg">
<Avatar />
<div>
<UserName />
<Badge />
</div>
</div>
)
}
// 최상위에서 사용
function App() {
return (
<main>
<h1>사용자 목록</h1>
<UserCard />
<UserCard /> {/* 재사용! */}
<UserCard />
</main>
)
}
UserCard를 세 번 쓰면 세 개의 카드가 렌더링됩니다. 이것이 재사용입니다. 다음 강의에서 배울 Props를 사용하면 각각 다른 내용을 보여줄 수 있습니다.
📂 파일 분리 — 실무 패턴
모든 컴포넌트를 한 파일에 쓰면 파일이 수백 줄이 되어 관리하기 어렵습니다. 실무에서는 컴포넌트 하나당 파일 하나를 원칙으로 합니다.
폴더 구조 예시:
src/
├── components/
│ ├── Avatar.tsx
│ ├── Badge.tsx
│ ├── UserCard.tsx
│ └── UserName.tsx
├── App.tsx
└── main.tsx
src/components/Avatar.tsx:
// 파일 마지막에 export default로 내보내기
export default function Avatar() {
return <img src="/avatar.png" alt="프로필" className="w-10 h-10 rounded-full" />
}
src/App.tsx에서 불러오기:
import Avatar from './components/Avatar'
import UserCard from './components/UserCard'
function App() {
return (
<main>
<Avatar />
<UserCard />
</main>
)
}
export default App
⚠️ 흔한 실수들
1. 컴포넌트 이름을 소문자로 시작
// ❌ 리액트가 HTML 태그로 인식함
function greeting() { return <h1>안녕</h1> }
<greeting /> // 브라우저 콘솔에 경고
// ✅
function Greeting() { return <h1>안녕</h1> }
<Greeting />
2. 컴포넌트 안에 다른 컴포넌트 선언
// ❌ 렌더링마다 Inner를 새로 생성 → 성능 문제, 상태 초기화
function Outer() {
function Inner() { return <p>안녕</p> } // 매 렌더마다 새 컴포넌트
return <Inner />
}
// ✅ 파일 최상단에 선언
function Inner() { return <p>안녕</p> }
function Outer() { return <Inner /> }
✅ 정리
- 컴포넌트는 JSX를 반환하는 함수이며, 이름은 반드시 대문자로 시작합니다.
- 작은 컴포넌트를 조합해 복잡한 UI를 만듭니다 — 레고 블록 방식.
- 컴포넌트마다 별도 파일로 분리하고
export default로 내보냅니다. - 컴포넌트 안에서 다른 컴포넌트를 선언하지 마세요 — 항상 파일 최상단에 선언합니다.
관련 주제
- 함수 컴포넌트 선언
- 컴포넌트 조합
- 파일 단위 분리
- 컴포넌트 재사용
- 개발·프로그래밍
- 개발·프로그래밍 강의
- 리액트 입문 — 컴포넌트로 만드는 웹
- 무료강의
- 무료 온라인 강의
- NUGUNA
- 누구나
