WeniVooks

검색

React 베이스캠프

함수 컴포넌트

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>&copy; 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>&copy; 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.js
src/
├── components/
│   ├── Header.js
│   ├── Article.js
│   ├── Sidebar.js
│   └── Footer.js
├── App.js
└── index.js
2.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 정리

함수 컴포넌트의 핵심을 배웠습니다:

  1. 함수 컴포넌트는 JSX를 반환하는 일반 JavaScript 함수입니다
  2. 여러 컴포넌트를 조합하여 복잡한 UI를 구성할 수 있습니다
  3. 파일을 분리하여 코드를 체계적으로 관리할 수 있습니다
  4. JavaScript 로직을 자유롭게 활용할 수 있습니다
  5. 클래스 컴포넌트보다 간결하고 성능상 이점이 있습니다

다음 장에서는 Props를 사용해서 컴포넌트 간에 데이터를 전달하는 방법을 알아보겠습니다.

2.1 컴포넌트란?2.3 Props 다루기