본문 바로가기
개발/웹 개발

Day 19: 컴포넌트 기반 아키텍처 (CBA)

1. 오늘의 학습 목표

학습 목표: React, Vue와 같은 현대 프론트엔드 프레임워크의 근간이 되는 컴포넌트 기반 아키텍처(Component-Based Architecture, CBA)의 개념을 이해합니다. 거대한 UI를 작고 독립적이며 재사용 가능한 '컴포넌트' 단위로 나누어 생각하고 설계하는 방법을 배웁니다.

핵심 요약: CBA는 레고 블록을 조립하듯 UI를 만드는 방식입니다. 이를 통해 복잡한 웹 애플리케이션을 더 효율적이고 체계적으로 개발하고 유지보수할 수 있습니다.


2. 핵심 개념 파헤치기

2.1. 컴포넌트 기반 아키텍처(CBA)란?

CBA는 웹 애플리케이션의 UI를 독립적인 부품들의 조합으로 바라보는 개발 방식입니다. 페이지 전체를 한 번에 만드는 것이 아니라, 버튼, 입력창, 프로필 카드 등 기능별로 UI를 작게 쪼개어 '컴포넌트'를 만듭니다. 그리고 이 컴포넌트들을 조립하여 더 큰 컴포넌트나 전체 페이지를 완성합니다.

 

2.2. 컴포넌트(Component)란 무엇인가?

컴포넌트는 특정 기능을 수행하는 UI의 독립적인 단위입니다. 자신만의 HTML 구조, 스타일(CSS), 그리고 동작 로직(JavaScript)을 모두 포함하고 있어 캡슐화되어 있습니다.

 

좋은 컴포넌트의 특징

  1. 재사용성 (Reusable): 하나의 컴포넌트를 여러 곳에서 반복해서 사용할 수 있습니다
  2. 독립성 (Independent): 다른 컴포넌트에 의존하지 않고 스스로 동작합니다.
  3. 캡슐화 (Encapsulated): 컴포넌트의 내부 구현은 외부에 감춰져 있어, 정해진 인터페이스(Props)를 통해서만 제어됩니다

3. 코드로 배우기

3.1. 구현 목표

아직 프레임워크를 배우기 전이므로, 순수 JavaScript 함수를 이용해 컴포넌트의 개념을 흉내 내 봅니다. 재사용 가능한 Button 컴포넌트와, 이 버튼을 사용하는 UserProfile 컴포넌트를 만들어 보겠습니다.

 

3.2. [1단계: Button 컴포넌트 만들기]

버튼의 텍스트를 인자로 받아 버튼 HTML 문자열을 반환하는 함수를 만듭니다. 이것이 우리의 첫 번째 재사용 가능한 컴포넌트입니다.

/**
 * 버튼 컴포넌트
 * @param {string} text - 버튼에 표시될 텍스트
 * @returns {string} - 버튼 HTML 문자열
 */
function Button(text) {
  return `<button class="my-button">${text}</button>`;
}

 

3.3. [2단계: UserProfile 컴포넌트 만들기]

사용자 객체를 인자로 받아 프로필 카드 HTML 문자열을 반환하는 함수를 만듭니다. 이 컴포넌트 내부에서 Button 컴포넌트를 호출하여 사용합니다.

/**
 * 유저 프로필 컴포넌트
 * @param {object} user - { name, role } 형태의 사용자 객체
 * @returns {string} - 유저 프로필 HTML 문자열
 */
function UserProfile(user) {
  return `
    <div class="profile-card">
      <h2>${user.name}</h2>
      <p>Role: ${user.role}</p>
      ${Button('View Details')} 
    </div>
  `;
}

 

3.4. [3단계: 컴포넌트 조립하여 렌더링하기]

만든 컴포넌트들을 호출하여 최종 UI를 만들고, DOM에 삽입하여 화면에 표시합니다.

const user1 = { name: 'Alice', role: 'Admin' };
const user2 = { name: 'Bob', role: 'User' };

const app = document.querySelector('#app');
app.innerHTML = `
  ${UserProfile(user1)}
  ${UserProfile(user2)}
`;

4. 전체 코드

 

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>Component Architecture</title>
  <style>
    body { font-family: sans-serif; display: flex; gap: 20px; }
    .profile-card { border: 1px solid #ccc; border-radius: 8px; padding: 16px; text-align: center; }
    .my-button { background-color: #007bff; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>Component Based Architecture Example</h1>
  <div id="app"></div>

  <script>
         //1. 재사용 가능한 버튼 컴포넌트
    function Button(text) {
      return `<button class="my-button">${text}</button>`;
    }

     //2. 버튼 컴포넌트를 사용하는 유저 프로필 컴포넌트
    function UserProfile(user) {
      return `
        <div class="profile-card">
          <h2>${user.name}</h2>
          <p>Role: ${user.role}</p>
          ${Button('View Details')}
        </div>
      `;
    }

       //3. 데이터를 기반으로 컴포넌트를 조립하여 렌더링
    const users = [
      { name: 'Alice', role: 'Admin' },
      { name: 'Bob', role: 'User' },
      { name: 'Charlie', role: 'Guest' }
    ];

    const appElement = document.querySelector('#app');
    appElement.innerHTML = users.map(user => UserProfile(user)).join('');
  </script>
</body>
</html>