함수 컴포넌트
2. 함수 컴포넌트
함수 컴포넌트는 React에서 가장 기본적이고 현재 권장되는 컴포넌트 작성 방법입니다. 일반 JavaScript 함수처럼 작성하며 JSX를 반환합니다.
2.1 함수 컴포넌트의 기본 형태
2.1.1 기본 문법
// 함수 선언문
function Welcome() {
return <h1>안녕하세요!</h1>;
}
// 함수 표현식
const Welcome = function() {
return <h1>안녕하세요!</h1>;
};
// 화살표 함수
const Welcome = () => {
return <h1>안녕하세요!</h1>;
};
// 화살표 함수 (축약형)
const Welcome = () => <h1>안녕하세요!</h1>;// 함수 선언문
function Welcome() {
return <h1>안녕하세요!</h1>;
}
// 함수 표현식
const Welcome = function() {
return <h1>안녕하세요!</h1>;
};
// 화살표 함수
const Welcome = () => {
return <h1>안녕하세요!</h1>;
};
// 화살표 함수 (축약형)
const Welcome = () => <h1>안녕하세요!</h1>;모든 형태가 동일하게 작동하지만, 함수 선언문이나 화살표 함수를 주로 사용합니다.
2.1.2 컴포넌트 사용하기
// Welcome 컴포넌트 정의
function Welcome() {
return <h1>React 베이스캠프에 오신 것을 환영합니다!</h1>;
}
// App 컴포넌트에서 Welcome 컴포넌트 사용
function App() {
return (
<div>
<Welcome />
<Welcome />
<Welcome />
</div>
);
}// Welcome 컴포넌트 정의
function Welcome() {
return <h1>React 베이스캠프에 오신 것을 환영합니다!</h1>;
}
// App 컴포넌트에서 Welcome 컴포넌트 사용
function App() {
return (
<div>
<Welcome />
<Welcome />
<Welcome />
</div>
);
}2.2 여러 개의 함수 컴포넌트 만들기
실제 애플리케이션에서는 여러 개의 컴포넌트를 조합하여 사용합니다.
// Header 컴포넌트
function Header() {
return (
<header>
<h1>나의 블로그</h1>
<nav>
<a href="#home">홈</a>
<a href="#about">소개</a>
<a href="#contact">연락처</a>
</nav>
</header>
);
}
// Article 컴포넌트
function Article() {
return (
<article>
<h2>React 학습 일기</h2>
<p>오늘은 React의 함수 컴포넌트에 대해 배웠습니다.</p>
<p>컴포넌트를 작은 단위로 나누니 코드가 더 깔끔해졌네요!</p>
<small>2025년 1월 9일</small>
</article>
);
}
// Sidebar 컴포넌트
function Sidebar() {
const categories = ['React', 'JavaScript', 'CSS', 'HTML'];
return (
<aside>
<h3>카테고리</h3>
<ul>
{categories.map((category, index) => (
<li key={index}>
<a href={`#${category.toLowerCase()}`}>{category}</a>
</li>
))}
</ul>
</aside>
);
}
// Footer 컴포넌트
function Footer() {
return (
<footer>
<p>© 2025 나의 블로그. 모든 권리 보유.</p>
</footer>
);
}
// 메인 App 컴포넌트
function App() {
return (
<div>
<Header />
<div>
<main>
<Article />
<Article />
</main>
<Sidebar />
</div>
<Footer />
</div>
);
}
export default App;// Header 컴포넌트
function Header() {
return (
<header>
<h1>나의 블로그</h1>
<nav>
<a href="#home">홈</a>
<a href="#about">소개</a>
<a href="#contact">연락처</a>
</nav>
</header>
);
}
// Article 컴포넌트
function Article() {
return (
<article>
<h2>React 학습 일기</h2>
<p>오늘은 React의 함수 컴포넌트에 대해 배웠습니다.</p>
<p>컴포넌트를 작은 단위로 나누니 코드가 더 깔끔해졌네요!</p>
<small>2025년 1월 9일</small>
</article>
);
}
// Sidebar 컴포넌트
function Sidebar() {
const categories = ['React', 'JavaScript', 'CSS', 'HTML'];
return (
<aside>
<h3>카테고리</h3>
<ul>
{categories.map((category, index) => (
<li key={index}>
<a href={`#${category.toLowerCase()}`}>{category}</a>
</li>
))}
</ul>
</aside>
);
}
// Footer 컴포넌트
function Footer() {
return (
<footer>
<p>© 2025 나의 블로그. 모든 권리 보유.</p>
</footer>
);
}
// 메인 App 컴포넌트
function App() {
return (
<div>
<Header />
<div>
<main>
<Article />
<Article />
</main>
<Sidebar />
</div>
<Footer />
</div>
);
}
export default App;2.3 컴포넌트 파일 분리하기
큰 프로젝트에서는 각 컴포넌트를 별도 파일로 분리하는 것이 좋습니다.
2.3.1 파일 구조
src/
├── components/
│ ├── Header.js
│ ├── Article.js
│ ├── Sidebar.js
│ └── Footer.js
├── App.js
└── index.jssrc/
├── components/
│ ├── Header.js
│ ├── Article.js
│ ├── Sidebar.js
│ └── Footer.js
├── App.js
└── index.js2.3.2 Header.js
function Header() {
return (
<header>
<h1>나의 블로그</h1>
<nav>
<a href="#home">홈</a>
<a href="#about">소개</a>
<a href="#contact">연락처</a>
</nav>
</header>
);
}
export default Header;function Header() {
return (
<header>
<h1>나의 블로그</h1>
<nav>
<a href="#home">홈</a>
<a href="#about">소개</a>
<a href="#contact">연락처</a>
</nav>
</header>
);
}
export default Header;2.3.3 App.js
import Header from './components/Header';
import Article from './components/Article';
import Sidebar from './components/Sidebar';
import Footer from './components/Footer';
function App() {
return (
<div>
<Header />
<div>
<main>
<Article />
<Article />
</main>
<Sidebar />
</div>
<Footer />
</div>
);
}
export default App;import Header from './components/Header';
import Article from './components/Article';
import Sidebar from './components/Sidebar';
import Footer from './components/Footer';
function App() {
return (
<div>
<Header />
<div>
<main>
<Article />
<Article />
</main>
<Sidebar />
</div>
<Footer />
</div>
);
}
export default App;2.4 컴포넌트 안에서 JavaScript 로직 사용하기
함수 컴포넌트 안에서는 일반적인 JavaScript 코드를 자유롭게 사용할 수 있습니다.
function UserProfile() {
// 변수 선언
const user = {
name: '김개발',
age: 28,
email: 'kim@example.com',
skills: ['JavaScript', 'React', 'Node.js', 'CSS']
};
// 함수 정의
const getSkillLevel = (skillCount) => {
if (skillCount >= 5) return '고급';
if (skillCount >= 3) return '중급';
return '초급';
};
const formatEmail = (email) => {
return email.toLowerCase();
};
// 조건부 로직
const isExperienced = user.age >= 25;
return (
<div>
<div>
<div>
{user.name.charAt(0)}
</div>
<h2>{user.name}</h2>
<p>{formatEmail(user.email)}</p>
</div>
<div>
<p><strong>나이:</strong> {user.age}세</p>
<p><strong>경험 수준:</strong> {getSkillLevel(user.skills.length)}</p>
<p>
<strong>상태:</strong>
<span>
{isExperienced ? ' 숙련된 개발자' : ' 신입 개발자'}
</span>
</p>
</div>
<div>
<h3>보유 기술</h3>
<div>
{user.skills.map((skill, index) => (
<span key={index}>
{skill}
</span>
))}
</div>
</div>
{isExperienced && (
<div>
<p>
🎉 경력직 개발자로 다양한 프로젝트 경험이 풍부합니다!
</p>
</div>
)}
</div>
);
}
function App() {
return (
<div>
<h1>팀 멤버 프로필</h1>
<UserProfile />
</div>
);
}
export default App;function UserProfile() {
// 변수 선언
const user = {
name: '김개발',
age: 28,
email: 'kim@example.com',
skills: ['JavaScript', 'React', 'Node.js', 'CSS']
};
// 함수 정의
const getSkillLevel = (skillCount) => {
if (skillCount >= 5) return '고급';
if (skillCount >= 3) return '중급';
return '초급';
};
const formatEmail = (email) => {
return email.toLowerCase();
};
// 조건부 로직
const isExperienced = user.age >= 25;
return (
<div>
<div>
<div>
{user.name.charAt(0)}
</div>
<h2>{user.name}</h2>
<p>{formatEmail(user.email)}</p>
</div>
<div>
<p><strong>나이:</strong> {user.age}세</p>
<p><strong>경험 수준:</strong> {getSkillLevel(user.skills.length)}</p>
<p>
<strong>상태:</strong>
<span>
{isExperienced ? ' 숙련된 개발자' : ' 신입 개발자'}
</span>
</p>
</div>
<div>
<h3>보유 기술</h3>
<div>
{user.skills.map((skill, index) => (
<span key={index}>
{skill}
</span>
))}
</div>
</div>
{isExperienced && (
<div>
<p>
🎉 경력직 개발자로 다양한 프로젝트 경험이 풍부합니다!
</p>
</div>
)}
</div>
);
}
function App() {
return (
<div>
<h1>팀 멤버 프로필</h1>
<UserProfile />
</div>
);
}
export default App;2.5 함수 컴포넌트의 특징
2.5.1 간결한 문법
- 클래스 컴포넌트보다 적은 코드로 작성 가능
render()메서드 불필요
2.5.2 성능상 이점
- 클래스 컴포넌트보다 메모리 사용량이 적음
- React의 최적화 기능을 더 잘 활용
2.5.3 함수형 프로그래밍
- JavaScript의 함수형 프로그래밍 패러다임과 잘 맞음
- 순수 함수의 개념 활용 가능
2.5.4 Hook 지원
- React Hook을 사용하여 상태와 생명주기 기능 활용 가능
2.6 실습: 간단한 카드 컴포넌트 모음
다양한 종류의 카드 컴포넌트를 만들어봅시다:
// 제품 카드 컴포넌트
function ProductCard() {
const product = {
name: 'MacBook Pro',
price: 2390000,
image: '💻',
rating: 4.8,
reviews: 1234
};
const formatPrice = (price) => {
return price.toLocaleString() + '원';
};
const generateStars = (rating) => {
const fullStars = Math.floor(rating);
const hasHalfStar = rating % 1 !== 0;
return '⭐'.repeat(fullStars) + (hasHalfStar ? '✨' : '');
};
return (
<div>
<div>
{product.image}
</div>
<h3>{product.name}</h3>
<p>
{formatPrice(product.price)}
</p>
<div>
{generateStars(product.rating)} ({product.rating})
</div>
<p>
{product.reviews}개 리뷰
</p>
<button>
장바구니 추가
</button>
</div>
);
}
// 날씨 카드 컴포넌트
function WeatherCard() {
const weather = {
city: '서울',
temperature: 15,
condition: '맑음',
humidity: 65,
windSpeed: 12
};
const getWeatherIcon = (condition) => {
switch (condition) {
case '맑음': return '☀️';
case '흐림': return '☁️';
case '비': return '🌧️';
case '눈': return '❄️';
default: return '🌤️';
}
};
return (
<div>
<h2>{weather.city}</h2>
<div>
{getWeatherIcon(weather.condition)}
</div>
<div>
{weather.temperature}°C
</div>
<p>{weather.condition}</p>
<div>
<div>
<p>습도</p>
<p>{weather.humidity}%</p>
</div>
<div>
<p>풍속</p>
<p>{weather.windSpeed}m/s</p>
</div>
</div>
</div>
);
}
// 메인 앱
function App() {
return (
<div>
<h1>함수 컴포넌트 예제</h1>
<div>
<ProductCard />
<WeatherCard />
</div>
</div>
);
}
export default App;// 제품 카드 컴포넌트
function ProductCard() {
const product = {
name: 'MacBook Pro',
price: 2390000,
image: '💻',
rating: 4.8,
reviews: 1234
};
const formatPrice = (price) => {
return price.toLocaleString() + '원';
};
const generateStars = (rating) => {
const fullStars = Math.floor(rating);
const hasHalfStar = rating % 1 !== 0;
return '⭐'.repeat(fullStars) + (hasHalfStar ? '✨' : '');
};
return (
<div>
<div>
{product.image}
</div>
<h3>{product.name}</h3>
<p>
{formatPrice(product.price)}
</p>
<div>
{generateStars(product.rating)} ({product.rating})
</div>
<p>
{product.reviews}개 리뷰
</p>
<button>
장바구니 추가
</button>
</div>
);
}
// 날씨 카드 컴포넌트
function WeatherCard() {
const weather = {
city: '서울',
temperature: 15,
condition: '맑음',
humidity: 65,
windSpeed: 12
};
const getWeatherIcon = (condition) => {
switch (condition) {
case '맑음': return '☀️';
case '흐림': return '☁️';
case '비': return '🌧️';
case '눈': return '❄️';
default: return '🌤️';
}
};
return (
<div>
<h2>{weather.city}</h2>
<div>
{getWeatherIcon(weather.condition)}
</div>
<div>
{weather.temperature}°C
</div>
<p>{weather.condition}</p>
<div>
<div>
<p>습도</p>
<p>{weather.humidity}%</p>
</div>
<div>
<p>풍속</p>
<p>{weather.windSpeed}m/s</p>
</div>
</div>
</div>
);
}
// 메인 앱
function App() {
return (
<div>
<h1>함수 컴포넌트 예제</h1>
<div>
<ProductCard />
<WeatherCard />
</div>
</div>
);
}
export default App;2.7 정리
함수 컴포넌트의 핵심을 배웠습니다:
- 함수 컴포넌트는 JSX를 반환하는 일반 JavaScript 함수입니다
- 여러 컴포넌트를 조합하여 복잡한 UI를 구성할 수 있습니다
- 파일을 분리하여 코드를 체계적으로 관리할 수 있습니다
- JavaScript 로직을 자유롭게 활용할 수 있습니다
- 클래스 컴포넌트보다 간결하고 성능상 이점이 있습니다
다음 장에서는 Props를 사용해서 컴포넌트 간에 데이터를 전달하는 방법을 알아보겠습니다.