본문 바로가기

함수 컴포넌트

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>;

모든 형태가 동일하게 작동하지만, 함수 선언문이나 화살표 함수를 주로 사용합니다.

2.1.2 컴포넌트 사용하기

// 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;

2.3 컴포넌트 파일 분리하기

큰 프로젝트에서는 각 컴포넌트를 별도 파일로 분리하는 것이 좋습니다.

2.3.1 파일 구조

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;

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;

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;

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;

2.7 정리

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

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

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