React 독학 가이드 4 - 컴포넌트 완벽 이해하기
React에서 가장 중요한 개념이 뭐냐고 물으면 저는 무조건 컴포넌트라고 답해요. 컴포넌트만 제대로 이해하면 React의 70%는 끝난 거예요. 진짜로요.
컴포넌트가 뭔가요?
컴포넌트는 쉽게 말해서 UI 조각이에요. 레고 블록이라고 생각하면 됩니다.
웹페이지를 만든다고 해볼게요. 네이버 메인을 예로 들면:
- 상단 네비게이션 바 = Header 컴포넌트
- 검색창 = SearchBar 컴포넌트
- 뉴스 목록 = NewsList 컴포넌트
- 각각의 뉴스 = NewsItem 컴포넌트
- 하단 푸터 = Footer 컴포넌트
이렇게 화면을 작은 조각으로 나누고, 각 조각을 컴포넌트로 만드는 거예요.
함수형 컴포넌트 만들기
요즘 React에서는 함수형 컴포넌트를 씁니다. 클래스형도 있는데 거의 안 써요.
가장 기본적인 컴포넌트
function Hello() {
return <h1>안녕하세요!</h1>;
}
끝이에요. 이게 컴포넌트입니다.
규칙:
- 함수 이름은 대문자로 시작 (Hello ⭕, hello ❌)
- JSX를 return 해야 함
- return은 하나의 요소만 가능
여러 요소를 return 하려면?
// ❌ 에러 발생
function Profile() {
return (
<h1>홍길동</h1>
<p>안녕하세요</p>
);
}
// ⭕ div로 감싸기
function Profile() {
return (
<div>
<h1>홍길동</h1>
<p>안녕하세요</p>
</div>
);
}
// ⭕ Fragment 사용 (불필요한 div 없애기)
function Profile() {
return (
<>
<h1>홍길동</h1>
<p>안녕하세요</p>
</>
);
}
<> </>는 Fragment라고 해요. 실제 DOM에는 아무것도 안 생기는데 여러 요소를 묶을 수 있어요.
화살표 함수로 컴포넌트 만들기
함수 선언식 대신 화살표 함수도 많이 써요:
// 함수 선언식
function Hello() {
return <h1>안녕하세요!</h1>;
}
// 화살표 함수
const Hello = () => {
return <h1>안녕하세요!</h1>;
};// 화살표 함수 (한 줄일 때)
const Hello = () => <h1>안녕하세요!</h1>;
세 개 다 똑같이 동작해요. 팀 컨벤션에 맞춰 쓰면 됩니다.
컴포넌트 사용하기
만든 컴포넌트는 HTML 태그처럼 사용해요:
function Hello() {
return <h1>안녕하세요!</h1>;
}
function App() {
return (
<div>
<Hello />
<Hello />
<Hello />
</div>
);
}
실행 결과:
안녕하세요!
안녕하세요!
안녕하세요!
같은 컴포넌트가 세 번 렌더링되었습니다
<Hello />처럼 태그로 쓰면 됩니다. 세 번 썼으니까 “안녕하세요!”가 세 번 나와요.
컴포넌트 파일 분리하기
컴포넌트가 많아지면 파일을 분리해야 해요.
파일 구조 예시
src/
components/
Header.jsx
Footer.jsx
Button.jsx
App.jsx
main.jsx
Header.jsx
function Header() {
return (
<header>
<h1>My Website</h1>
<nav>
<a href="/">홈</a>
<a href="/about">소개</a>
</nav>
</header>
);
}
export default Header;
마지막에 export default로 내보내야 다른 파일에서 쓸 수 있어요.
App.jsx에서 불러오기
import Header from './components/Header';
import Footer from './components/Footer';
function App() {
return (
<div>
<Header />
<main>
<p>메인 콘텐츠</p>
</main>
<Footer />
</div>
);
}
export default App;
import로 불러와서 사용하면 됩니다.
실전 예제: 프로필 카드 만들기
실제로 컴포넌트를 만들어볼게요.
ProfileCard.jsx
function ProfileCard() {
return (
<div className="profile-card">
<img
src="https://via.placeholder.com/100"
alt="프로필"
/>
<h2>김개발</h2>
<p>Frontend Developer</p>
<div className="skills">
<span>React</span>
<span>JavaScript</span>
<span>CSS</span>
</div>
</div>
);
}
export default ProfileCard;
스타일 추가 (ProfileCard.css)
.profile-card {
border: 1px solid #ddd;
border-radius: 12px;
padding: 20px;
text-align: center;
max-width: 250px;
}
.profile-card img {
border-radius: 50%;
width: 100px;
height: 100px;
}
.profile-card h2 {
margin: 10px 0 5px;
}
.profile-card p {
color: #666;
margin: 0;
}
.skills {
margin-top: 15px;
display: flex;
gap: 8px;
justify-content: center;
flex-wrap: wrap;
}
.skills span {
background: #e3f2fd;
color: #1976d2;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
}
사용하기
import ProfileCard from './components/ProfileCard';
import './components/ProfileCard.css';
function App() {
return (
<div>
<h1>우리 팀</h1>
<div style={{ display: 'flex', gap: '20px' }}>
<ProfileCard />
<ProfileCard />
<ProfileCard />
</div>
</div>
);
}
이렇게 하면 같은 프로필 카드가 3개 나와요. 근데 지금은 다 똑같죠? 다음 글에서 배울 Props를 쓰면 각각 다른 데이터를 넣을 수 있어요.
컴포넌트 분리 기준
“어디서 컴포넌트를 나눠야 하지?” 고민될 때 이 기준을 쓰세요:
1. 반복되는 UI
// ❌ 반복되는 코드
<div className="card">상품1</div>
<div className="card">상품2</div>
<div className="card">상품3</div>
// ⭕ 컴포넌트로 분리
<ProductCard name="상품1" />
<ProductCard name="상품2" />
<ProductCard name="상품3" />
2. 독립적인 기능
헤더, 푸터, 사이드바처럼 독립적으로 동작하는 건 분리하세요.
3. 너무 길어질 때
한 파일이 200줄 넘어가면 분리를 고려하세요.
4. 재사용 가능성
다른 곳에서도 쓸 것 같으면 분리하세요. Button, Input 같은 건 무조건 분리하는 게 좋아요.
컴포넌트 네이밍 컨벤션
// ⭕ 좋은 예
function UserProfile() { }
function ProductCard() { }
function NavigationBar() { }
// ❌ 나쁜 예
function userprofile() { } // 소문자 시작
function User_Profile() { } // 언더스코어
function up() { } // 의미 없는 이름
- PascalCase 사용 (첫 글자 대문자)
- 명확한 이름 사용
- 역할을 설명하는 이름 사용
다음 단계
컴포넌트 기초를 배웠으니, 다음 글에서는 JSX에 대해 자세히 다뤄볼게요. JSX는 React에서 UI를 표현하는 문법인데, 알아두면 정말 편해요.
컴포넌트 개념이 조금 익숙해졌으면, 직접 여러 컴포넌트를 만들어보세요. Header, Footer, Button, Card 같은 것들요. 만들다 보면 자연스럽게 감이 와요!
React 시리즈 탐색:
← 블로그 목록으로