프론트엔드에서 사용하기 좋은 Design Pattern - Atomic Deisgn Pattern

Kychann·2025년 4월 29일
post-thumbnail

🧪 Atomic Design Pattern?

Atomic Design은 컴포넌트를 작은 단위(원자) 부터 시작해 점점 큰 단위(조직/페이지)로 조립하는 UI 설계 방법론 이다.

복잡한 UI를 계층적이고 체계적으로 구성할 수 있게 도와준다.

핵심

“작은 컴포넌트를 먼저 만들고, 이걸 조립해서 점점 큰 컴포넌트를 만든다” 이다.

⚡ Atomic Design 5단계

단계설명React 예시
Atoms (원자)가장 작은 단위, 쪼개질 수 없음Button, Input, Label, Icon
Molecules (분자)원자들이 모여 기능을 수행Input + Label 조합, SearchBar
Organisms (유기체)여러 분자가 모여 완성된 UI 블록Header, Card, Sidebar
Templates (템플릿)유기체를 배치해 페이지 구조 형성상품 리스트 템플릿, 대시보드 뷰 템플릿
Pages (페이지)실제 데이터와 연결된 완성 페이지ProductDetailPage, MyProfilePage

🔥 React 예시로 보는 Atomic Design

프로젝트 구조 예시

/src
  /components
    /atoms
      Button.tsx
      Input.tsx
      Label.tsx
    /molecules
      InputWithLabel.tsx
      SearchBar.tsx
    /organisms
      Header.tsx
      Footer.tsx
      ProductCard.tsx
    /templates
      ProductListTemplate.tsx
    /pages
      ProductListPage.tsx

1. Atoms (원자)

// components/atoms/Button.tsx
import React from 'react';

export const Button = ({ children, onClick }: { children: React.ReactNode; onClick: () => void }) => {
  return (
    <button onClick={onClick} className="px-4 py-2 bg-blue-500 text-white rounded">
      {children}
    </button>
  );
};

👉 작고 독립적인 버튼 하나. (이 자체로 의미를 가짐)

2. Molecules (분자)

// components/molecules/SearchBar.tsx
import React from 'react';
import { Input } from '../atoms/Input';
import { Button } from '../atoms/Button';

export const SearchBar = ({ onSearch }: { onSearch: (query: string) => void }) => {
  const [query, setQuery] = React.useState("");

  return (
    <div className="flex space-x-2">
      <Input value={query} onChange={(e) => setQuery(e.target.value)} />
      <Button onClick={() => onSearch(query)}>Search</Button>
    </div>
  );
};

👉 Input + Button 조합 = 새로운 기능(검색)을 가짐.

3. Organisms (유기체)

// components/organisms/Header.tsx
import React from 'react';
import { SearchBar } from '../molecules/SearchBar';

export const Header = () => {
  return (
    <header className="flex items-center justify-between p-4 bg-gray-100">
      <h1 className="text-xl font-bold">WeKick</h1>
      <SearchBar onSearch={(query) => console.log("Searching for", query)} />
    </header>
  );
};

👉 여러 분자들(SearchBar 등)이 모여서 하나의 UI 블록(헤더)이 됨.

4. Templates (템플릿)

// components/templates/ProductListTemplate.tsx
import React from 'react';
import { ProductCard } from '../organisms/ProductCard';

export const ProductListTemplate = ({ products }: { products: Product[] }) => {
  return (
    <div className="grid grid-cols-2 gap-4">
      {products.map((product) => (
        <ProductCard key={product.id} product={product} />
      ))}
    </div>
  );
};

👉 페이지 레이아웃 구조를 담당. 데이터는 아직 들어오지 않았음.

5. Pages (페이지)

// components/pages/ProductListPage.tsx
import React from 'react';
import { ProductListTemplate } from '../templates/ProductListTemplate';
import { productsMock } from '../../mocks/productsMock';

export const ProductListPage = () => {
  return <ProductListTemplate products={productsMock} />;
};

👉 템플릿에 진짜 데이터를 주입해서 완성된 페이지.


🧠 정리: Atomic Design을 왜 쓰나?

장점설명
재사용성작은 컴포넌트 단위로 쪼개면, 어디서든 쉽게 재사용 가능
유지보수성기능 추가/수정할 때 전체 구조를 깨지 않고 부분만 수정 가능
명확한 계층프로젝트 구조가 명확해져 협업/리팩토링 시 유리
스케일 확장서비스가 커져도 관리 가능한 컴포넌트 시스템 유지
profile
어,, 저 아닌데요?

0개의 댓글