누구나 로고
オンライン講座企業・団体研修ライブラリトレンドインサイト無料コースお知らせお問い合わせ採用サイト

カスタマーサポート

  • お知らせ
  • よくある質問
  • footer.contact
  • コミュニティ

ご利用案内

  • 利用規約
  • プライバシーポリシー
  • 返金ポリシー

サービス

  • 会社紹介
  • 新規登録
  • 新着コース
  • 無料コース
누구나 로고
利用規約プライバシーポリシー返金ポリシー

상호명: NUGUNA  |  대표자: 정우진  |  사업자등록번호: 392-32-01817  |  통신판매업신고: 제 2026-서울양천-0564 호

주소: 서울특별시 양천구 목동서로 100, 309동 1006호  |  이메일: nugunapass@gmail.com  |  전화: 010-6395-3043

© 2026 NUGUNA. All rights reserved.

KB예금주인증
ホームコースライブラリお問い合わせMY
관리자
모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.
로그인무료 회원가입
강좌리액트 입문 — 컴포넌트로 만드는 웹4강

4강 / 전체 8강

컴포넌트 만들기

4분 읽기 조회 55

함수 컴포넌트를 선언하고 조합하는 방법, 컴포넌트를 파일로 분리하는 패턴, 재사용의 본질적 의미를 코드로 배웁니다.

🧱 컴포넌트란 무엇인가 — 다시 한 번

리액트에서 컴포넌트는 UI의 독립적인 단위입니다. 기술적으로는 JSX를 반환하는 JavaScript 함수입니다. 단순하지만 이 개념 하나로 복잡한 UI를 구조적으로 만들 수 있습니다. 이번 강의에서는 컴포넌트를 직접 만들고, 조합하고, 파일로 분리하는 모든 과정을 배웁니다.

✍️ 함수 컴포넌트 선언

함수 컴포넌트는 JSX를 반환하는 일반 함수입니다. 두 가지 규칙만 기억하세요:

  1. 이름은 대문자로 시작해야 합니다. (MyComponent O, myComponent X)
  2. 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
  • 누구나

목차

이전 3강JSX 기초
다음 5강 Props로 데이터 전달
1.리액트란 무엇인가
2.개발 환경 만들기 — Vite
3.JSX 기초
4.컴포넌트 만들기
5.Props로 데이터 전달
6.State와 useState
7.이벤트 처리
8.조건부 렌더링