지난 장의 재료를 하나로 묶으면 컴포넌트가 된다
지난 장에서 웹페이지를 네 가지 재료로 나누어 보았습니다.
HTML = 구조
CSS = 스타일
JS = 동작
Data = 바뀔 수 있는 콘텐츠React는 이 재료들을 화면 단위로 묶어 다루는 방식입니다.
예를 들어 포트폴리오 사이트의 프로젝트 카드를 떠올려 봅시다.
Project Card
├─ HTML: 카드 안에 이미지, 제목, 설명, 태그가 있다
├─ CSS: 카드의 여백, 둥근 모서리, 그림자, 그리드 규칙이 있다
├─ JS: 클릭하면 상세 페이지로 이동할 수 있다
└─ Data: 프로젝트 제목, 기간, 썸네일, 역할이 달라진다이 카드가 한 번만 쓰인다면 그냥 만들어도 됩니다. 하지만 포트폴리오에는 프로젝트 카드가 여러 개 들어갑니다. 소개 카드, 섹션 제목, 버튼, 태그도 반복됩니다.
이때 React의 핵심 개념인 컴포넌트가 등장합니다.
Next.js 공식 Learn에서는 React의 UI를 작은 구성 요소로 나눌 수 있고, 이 구성 요소를 재사용 가능한 코드 조각으로 만들 수 있다고 설명합니다. 레고 블록처럼 작은 조각을 조합해 더 큰 화면을 만드는 방식입니다.1
디자이너에게는 이렇게 이해하면 충분합니다.
React 컴포넌트
= 화면에서 반복되는 UI 패턴을 재사용 가능한 단위로 만든 것즉, 개발자가 "이 부분 컴포넌트화할게요"라고 말할 때의 의미는 단순히 코드를 예쁘게 정리하겠다는 뜻이 아닙니다.
디자인 시스템의 부품을 실제 제품 코드 안에 구현하겠다는 뜻에 가깝습니다.

React 컴포넌트는 Figma 메인 컴포넌트에 가깝다
Figma에서 버튼을 매번 새로 그리지 않습니다.
보통은 Button이라는 메인 컴포넌트를 만들고, 필요한 곳마다 인스턴스를 배치합니다. 메인 컴포넌트의 패딩이나 radius를 수정하면 연결된 인스턴스에도 같은 규칙이 반영됩니다.
React도 비슷합니다.
Figma
메인 컴포넌트 Button 생성
↓
여러 화면에서 Button 인스턴스 사용
React
Button 컴포넌트 생성
↓
여러 페이지에서 <Button /> 사용포트폴리오 사이트의 프로필 카드를 예로 들어 보겠습니다.
ProfileCard 컴포넌트
├─ 프로필 이미지
├─ 이름
├─ 직무
└─ 짧은 소개 문장React에서는 이 구조를 하나의 컴포넌트로 만들 수 있습니다.
function ProfileCard() {
return (
<article>
<img src='/profile.png' alt='프로필 사진' />
<h3>김OO</h3>
<p>Product Designer</p>
<p>문제를 구조화하고 제품 경험을 설계합니다.</p>
</article>
);
}처음 보면 HTML과 비슷해 보입니다. 이것은 JSX입니다. JSX는 JavaScript 안에서 HTML처럼 UI 구조를 적을 수 있게 해 주는 문법입니다.
중요한 규칙은 두 가지입니다.
React 컴포넌트 이름은 보통 대문자로 시작합니다.
ProfileCard처럼 씁니다.만든 컴포넌트는 HTML 태그처럼
<ProfileCard />형태로 사용합니다.
<ProfileCard />Figma식으로 말하면, 위 코드는 캔버스에 ProfileCard 인스턴스 하나를 올려놓는 것과 비슷합니다.
인스턴스마다 내용이 달라져야 한다면 props를 쓴다
그런데 문제가 있습니다.
Figma 인스턴스는 모두 같은 모양을 공유하지만, 안의 텍스트나 이미지, 상태는 바꿀 수 있습니다.
예를 들어 같은 버튼 컴포넌트라도 이렇게 달라집니다.
Button 인스턴스 A: 문의하기
Button 인스턴스 B: 프로젝트 보기
Button 인스턴스 C: 이력서 다운로드React에서도 같은 일이 필요합니다.
ProjectCard의 구조는 같지만, 카드마다 제목과 설명, 이미지가 달라져야 합니다. 이때 사용하는 것이 props입니다.
props는 properties의 줄임말입니다. React 컴포넌트에 전달하는 속성입니다. 공식 Learn에서는 HTML 태그에 src나 href 같은 속성을 전달하듯, React 컴포넌트에도 props를 전달해 화면에 보이는 내용이나 동작을 바꿀 수 있다고 설명합니다.2
디자이너에게는 이렇게 이해하면 됩니다.
props
= Figma Component Properties, Variants, 인스턴스 오버라이드처럼
같은 구조에 다른 값과 상태를 넣는 방식| Figma에서 익숙한 것 | React에서 비슷한 것 |
|---|---|
| Text property | title, description 같은 텍스트 props |
| Instance swap | icon, thumbnail 같은 이미지·아이콘 props |
| Variant | variant='primary', size='large' 같은 상태 props |
| Boolean property | isFeatured, showImage 같은 true/false props |
| 인스턴스별 텍스트 수정 | 컴포넌트 사용 시 다른 props 전달 |
프로필 카드를 props로 바꾸면 이렇게 생각할 수 있습니다.
function ProfileCard({ name, role, description }) {
return (
<article>
<h3>{name}</h3>
<p>{role}</p>
<p>{description}</p>
</article>
);
}그리고 사용할 때는 이렇게 값을 넣습니다.
<ProfileCard
name='김OO'
role='Product Designer'
description='문제를 구조화하고 제품 경험을 설계합니다.'
/>여기서 {name}은 "이 자리에 name이라는 값을 넣어 주세요"라는 뜻입니다.
Figma로 비유하면 텍스트 레이어에 직접 문장을 박아 두는 대신, 메인 컴포넌트에 name이라는 텍스트 속성을 열어 두고 인스턴스마다 값을 바꾸는 것과 같습니다.
props로 뺄 것과 고정할 것을 나누기
컴포넌트를 잘 만들려면 먼저 질문해야 합니다.
무엇은 항상 같고, 무엇은 매번 달라지는가?
포트폴리오의 ProfileCard를 예로 들어 보겠습니다.
| 구분 | 예시 |
|---|---|
| 고정되는 것 | 카드 구조, 이미지 위치, 이름과 직무의 순서, 기본 여백 |
| 바뀔 수 있는 것 | 이름, 직무, 소개 문장, 프로필 이미지, 링크 |
| 상태로 달라질 수 있는 것 | 강조 카드인지, 링크가 있는지, 이미지가 있는지 |
고정되는 것은 컴포넌트 안에 둡니다.
바뀌는 것은 props로 뺍니다.
ProfileCard
├─ 고정: 카드 레이아웃, 텍스트 계층, 간격 규칙
└─ props: name, role, description, imageUrl, linkUrl이 사고방식은 디자인 시스템과 거의 같습니다.
Figma 컴포넌트를 만들 때도 모든 레이어를 자유롭게 바꾸게 두지는 않습니다. 바꿔도 되는 속성과 바꾸면 안 되는 구조를 나눕니다.
React 컴포넌트도 마찬가지입니다.
props를 너무 적게 열어 두면 재사용하기 어렵습니다. 반대로 모든 것을 props로 열어 두면 컴포넌트의 일관성이 깨집니다.
좋은 컴포넌트는 자유도가 무한한 것이 아니라, 필요한 변화만 안전하게 허용하는 부품입니다.
ProjectCard: 반복되는 UI를 하나의 컴포넌트로 바꾸기
이제 포트폴리오 사이트의 핵심인 프로젝트 카드를 보겠습니다.
Figma에서는 보통 프로젝트 카드 3개를 복사해서 배치합니다.
[Project Card] [Project Card] [Project Card]시각적으로는 문제가 없어 보입니다. 하지만 개발에서는 이 세 카드가 정말 같은 패턴인지 확인해야 합니다.
세 카드가 같은 컴포넌트가 될 수 있는 조건
- 이미지 위치가 같다
- 제목, 설명, 태그의 계층이 같다
- 클릭 영역의 규칙이 같다
- 모바일에서 쌓이는 방식이 같다
- 다른 것은 안에 들어가는 데이터뿐이다이 조건이 맞다면 ProjectCard 컴포넌트로 만들 수 있습니다.
<ProjectCard
title='온보딩 개선 프로젝트'
summary='첫 사용자의 이탈 지점을 줄이기 위해 가입 흐름을 재설계했습니다.'
role='UX 리서치 · 플로우 설계'
period='2025'
/>
<ProjectCard
title='커머스 검색 경험 개선'
summary='검색 결과 탐색과 필터 사용성을 개선했습니다.'
role='프로덕트 디자인'
period='2024'
/>같은 ProjectCard를 두 번 사용하지만, props가 다르기 때문에 화면에는 다른 내용이 보입니다.
디자이너 관점에서는 이렇게 읽으면 됩니다.
ProjectCard 메인 컴포넌트는 하나
인스턴스는 여러 개
각 인스턴스의 title, summary, role, period만 다름여기서 중요한 것은 코드 문법이 아닙니다.
중요한 것은 반복되는 UI를 구조와 데이터로 분리해서 보는 눈입니다.
구조
= 카드라는 틀
데이터
= 카드 안에 들어가는 프로젝트별 내용이 구분이 되면 7장에서 API를 배울 때도 훨씬 쉬워집니다. API는 결국 이런 데이터가 코드 밖에서 들어오는 통로이기 때문입니다.
SectionTitle: 작은 컴포넌트도 디자인 규칙을 지킨다
컴포넌트는 큰 카드에만 쓰는 것이 아닙니다.
포트폴리오 사이트에는 반복되는 섹션 제목도 있습니다.
Featured Work
대표 프로젝트를 소개합니다.
About
제가 일하는 방식을 소개합니다.
Contact
함께 이야기하고 싶다면 연락 주세요.이 제목 영역의 스타일이 매번 같다면 SectionTitle 컴포넌트로 만들 수 있습니다.
<SectionTitle
label='Featured Work'
title='대표 프로젝트'
description='문제를 정의하고 제품 경험으로 연결한 사례입니다.'
/>SectionTitle은 작지만 중요한 역할을 합니다.
섹션 제목의 계층을 일정하게 유지합니다.
label, title, description의 순서를 통일합니다.
여백과 타이포그래피 규칙을 반복해서 쓰게 해 줍니다.
나중에 제목 스타일을 바꿀 때 한 곳만 수정하면 됩니다.
디자인 시스템에서 텍스트 스타일과 섹션 패턴을 정의하는 것과 같습니다.
작은 컴포넌트라도 반복되고, 의미가 있고, 규칙을 지켜야 한다면 분리할 가치가 있습니다.
children: 오토레이아웃 프레임 안에 다른 레이어 넣기
props가 "값을 전달하는 방식"이라면, children은 "컴포넌트 안에 다른 내용을 넣을 수 있게 열어 둔 자리"입니다.
Figma의 오토레이아웃 프레임을 떠올려 봅시다.
프레임에는 패딩, gap, 배경색, radius가 정해져 있습니다. 그런데 그 안에는 텍스트를 넣을 수도 있고, 버튼을 넣을 수도 있고, 카드 여러 개를 넣을 수도 있습니다.
Auto Layout Frame
├─ 패딩 24px
├─ gap 16px
├─ radius 16px
└─ 안쪽 레이어는 상황에 따라 달라짐React의 children도 비슷합니다.
function Card({ children }) {
return (
<div className='card'>
{children}
</div>
);
}이제 Card 안에 원하는 내용을 넣을 수 있습니다.
<Card>
<h3>온보딩 개선 프로젝트</h3>
<p>첫 사용자의 이탈을 줄이기 위해 가입 흐름을 재설계했습니다.</p>
</Card>여기서 Card는 바깥 틀을 담당합니다.
안에 들어가는 제목과 문단은 children으로 들어갑니다.
Card 컴포넌트
= 바깥 프레임, 패딩, 배경, radius 담당
children
= 그 안에 들어오는 실제 레이어들이 개념을 알면 컴포넌트를 더 유연하게 조합할 수 있습니다.
예를 들어 Section 컴포넌트는 섹션의 최대 너비와 위아래 여백을 담당하고, 그 안에는 SectionTitle, ProjectCard, ProfileCard가 들어갈 수 있습니다.
<Section>
<SectionTitle
label='Featured Work'
title='대표 프로젝트'
description='최근 작업한 프로젝트를 소개합니다.'
/>
<ProjectCard title='온보딩 개선 프로젝트' />
<ProjectCard title='커머스 검색 경험 개선' />
</Section>디자이너식으로 말하면, Section은 오토레이아웃 프레임이고 그 안에 어떤 레이어를 넣을지는 상황에 따라 달라집니다.
화면은 컴포넌트 트리로 조립된다
React에서는 컴포넌트 안에 다른 컴포넌트를 넣을 수 있습니다. 이렇게 중첩된 구조를 만들면 화면 전체가 하나의 트리처럼 보입니다.
포트폴리오 홈 화면을 컴포넌트 트리로 그리면 이런 모습입니다.
HomePage
├─ Header
│ ├─ Logo
│ └─ Navigation
├─ Hero
│ ├─ SectionTitle
│ └─ ProfileCard
├─ FeaturedProjects
│ ├─ SectionTitle
│ ├─ ProjectCard
│ ├─ ProjectCard
│ └─ ProjectCard
└─ ContactSection
├─ SectionTitle
└─ ContactButton이 트리는 Figma의 레이어 패널과 비슷합니다.
다만 차이가 있습니다. Figma의 레이어 패널은 주로 시각적 구조를 보여 줍니다. React의 컴포넌트 트리는 시각적 구조뿐 아니라 데이터가 어디로 전달되는지, 어떤 부품이 재사용되는지도 함께 보여 줍니다.
Figma 레이어 패널
= 화면이 어떻게 쌓여 있는가
React 컴포넌트 트리
= 화면이 어떤 부품으로 조립되고, 값이 어디로 전달되는가이 감각이 생기면 개발자와 대화할 때 훨씬 구체적으로 말할 수 있습니다.
"이 카드 3개 디자인 같아요"에서 멈추지 않고, 이렇게 말할 수 있습니다.
이 세 카드는 같은
ProjectCard컴포넌트로 만들고, 제목·설명·기간·태그만 props로 다르게 넣으면 될까요?
이 질문은 이미 구현 방식에 가까운 질문입니다.
실습: 포트폴리오 홈 화면을 컴포넌트로 쪼개기
이번 실습은 코드를 실행하지 않아도 됩니다.
Figma 파일이나 종이에 포트폴리오 홈 화면을 하나 놓고, 반복되는 UI를 컴포넌트 후보로 표시해 봅니다.
1단계: 반복되는 패턴 찾기
먼저 같은 형태가 반복되는 부분을 표시합니다.
- 프로젝트 카드가 여러 번 반복된다
- 섹션 제목 패턴이 반복된다
- 태그 pill이 반복된다
- 버튼 스타일이 반복된다
- 카드형 레이아웃이 반복된다반복된다고 해서 무조건 컴포넌트가 되는 것은 아닙니다. 하지만 반복은 좋은 출발점입니다.
2단계: 고정되는 것과 달라지는 것 나누기
다음 표처럼 정리해 봅니다.
| 컴포넌트 후보 | 고정되는 것 | props로 뺄 것 |
|---|---|---|
ProfileCard | 카드 구조, 텍스트 순서, 기본 간격 | name, role, description, imageUrl |
ProjectCard | 썸네일 위치, 제목 계층, 설명 영역, 클릭 규칙 | title, summary, period, role, thumbnailUrl, href |
SectionTitle | label/title/description 순서, 타이포그래피 | label, title, description |
Tag | pill 모양, radius, padding | text, variant |
Section | 최대 너비, 위아래 여백 | children |
이 표는 개발자에게 그대로 전달해도 좋습니다.
코드 명세서까지는 아니지만, 디자인 의도를 구현 단위로 번역한 문서가 됩니다.
3단계: children이 필요한 곳 표시하기
안쪽 내용이 자주 달라지는 큰 틀에는 children을 생각해 봅니다.
Section
└─ 안에 들어가는 내용은 매번 달라짐
Card
└─ 어떤 카드는 프로젝트 내용
└─ 어떤 카드는 프로필 내용
└─ 어떤 카드는 연락처 내용이런 경우에는 props로 모든 내용을 하나하나 넘기는 것보다, 안쪽을 열어 두는 방식이 더 자연스러울 수 있습니다.
Figma에서 오토레이아웃 프레임을 만들고 그 안에 필요한 레이어를 넣는 감각과 같습니다.
4단계: JSX 트리를 손으로 써 보기
마지막으로 화면을 코드처럼 그려 봅니다. 정확한 문법보다 구조를 보는 것이 목적입니다.
<HomePage>
<Header />
<Hero>
<ProfileCard />
</Hero>
<Section>
<SectionTitle />
<ProjectCard />
<ProjectCard />
<ProjectCard />
</Section>
<Section>
<SectionTitle />
<ContactButton />
</Section>
</HomePage>이 정도만 해도 큰 변화가 생깁니다.
이제 화면을 한 장의 정적인 이미지로만 보지 않고, 재사용 가능한 부품들의 조합으로 보기 시작한 것입니다.
React를 알면 디자인 시스템 대화가 달라진다
React를 배운다고 해서 디자이너가 당장 개발자가 되어야 하는 것은 아닙니다.
하지만 React의 컴포넌트 사고를 알면 디자인 시스템을 더 현실적으로 다룰 수 있습니다.
Figma에서 컴포넌트를 잘 만들었다고 해서 제품 코드도 자동으로 좋아지지는 않습니다. 개발자가 같은 구조를 코드 컴포넌트로 만들고, props로 변화를 통제하고, 여러 화면에서 재사용해야 실제 제품 안에서도 디자인 시스템이 작동합니다.
Figma 디자인 시스템
= 디자이너가 쓰는 UI 부품의 원본
React 컴포넌트
= 실제 제품에서 실행되는 UI 부품의 구현그래서 중요한 질문은 "Figma에 컴포넌트가 있나요?"에서 끝나지 않습니다.
더 좋은 질문은 이것입니다.
이 Figma 컴포넌트가 코드에서는 어떤 React 컴포넌트와 연결되나요?
이 질문을 할 수 있으면 핸드오프의 수준이 달라집니다.
디자인 파일을 넘기는 사람이 아니라, 제품 UI의 구조를 함께 설계하는 사람이 됩니다.
이번 장에서 기억할 것
React의 핵심은 컴포넌트입니다.
컴포넌트는 화면을 재사용 가능한 작은 단위로 나누는 방식입니다. 디자이너에게는 Figma 메인 컴포넌트와 인스턴스의 관계로 이해하면 쉽습니다.
React 컴포넌트
= Figma 메인 컴포넌트에 가까움
컴포넌트 사용부
= Figma 인스턴스에 가까움
props
= Component Properties, Variants, 인스턴스 오버라이드에 가까움
children
= 오토레이아웃 프레임 안에 들어가는 레이어에 가까움
컴포넌트 트리
= 화면이 부품으로 조립된 구조포트폴리오 사이트에서는 ProfileCard, ProjectCard, SectionTitle 같은 컴포넌트를 먼저 떠올릴 수 있습니다.
컴포넌트화의 핵심 질문은 단순합니다.
무엇이 반복되는가?
무엇이 고정되는가?
무엇이 달라지는가?
어떤 값을 props로 열어 둘 것인가?
어디를 children으로 열어 둘 것인가?이 질문에 답할 수 있으면, 개발자가 말하는 "컴포넌트화"가 더 이상 막연한 코드 용어로 들리지 않습니다.
그것은 디자인 시스템이 실제 제품 안에서 작동하는 방식입니다.
디자이너가 개발자에게 이제 할 수 있는 질문
이 UI는 하나의 React 컴포넌트로 분리하는 것이 좋을까요?
Figma의 이 메인 컴포넌트는 코드에서 어떤 컴포넌트와 대응되나요?
이 카드에서 고정되는 구조와 props로 열어 둘 값은 무엇인가요?
ProjectCard의title,summary,thumbnail,href같은 값은 props로 받을 수 있나요?이 상태 차이는 Figma Variant처럼
variantprop으로 처리하나요, 아니면 별도 컴포넌트로 나누나요?이미지가 없는 경우, 링크가 없는 경우, 설명이 긴 경우도 같은 컴포넌트가 감당하나요?
이 컴포넌트 안쪽 내용은 고정인가요, 아니면
children처럼 열어 두는 구조가 더 좋나요?섹션 제목, 태그, 버튼처럼 작은 요소도 코드 컴포넌트로 관리되고 있나요?
디자인 시스템의 Component Properties와 코드의 props 이름을 맞출 수 있나요?
이 컴포넌트를 다른 페이지에서도 재사용할 계획이 있나요?
참고
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.
