연휴 잘 보내고 계신가요? 오늘은 컴퍼넌트에 대해 이야기해 보려합니다.
지난 두 번의 여정을 통해 React의 세계관과 UI 렌더링의 핵심 문법인 JSX를 살펴보았습니다. 이제 React 애플리케이션을 구성하는 가장 기본적인 building block이자 핵심 단위인 컴포넌트 (Component)에 대해 본격적으로 알아보는 시간을 갖겠습니다. 이번 글에서는 React 컴포넌트 중에서도 가장 기본적인 형태이며 현대 React 개발의 주류를 이루는 함수형 컴포넌트 (Functional Component)에 대해 탐구해 보겠습니다.
컴포넌트란 무엇일까요?
React에서 컴포넌트는 독립적이고 재사용 가능한 UI의 한 조각을 의미합니다. 마치 레고 블록처럼, 작고 특정한 기능을 수행하는 컴포넌트들을 조합하여 복잡하고 동적인 사용자 인터페이스를 구축할 수 있습니다. 각 컴포넌트는 자체적인 로직과 데이터를 가질 수 있으며, 다른 컴포넌트와 상호작용하며 애플리케이션의 전체적인 UI를 구성합니다.
컴포넌트 기반 아키텍처는 다음과 같은 중요한 이점을 제공합니다.
- 재사용성 (Reusability): 한번 작성된 컴포넌트는 애플리케이션 내의 여러 곳에서 재사용될 수 있어 개발 효율성을 높이고 코드 중복을 줄여줍니다.
- 모듈성 (Modularity): UI를 독립적인 컴포넌트 단위로 나누어 개발함으로써 코드의 구조를 명확하게 하고 유지보수를 용이하게 합니다. 각 컴포넌트는 특정 기능에 집중하므로 이해하고 수정하기 쉽습니다.
- 테스트 용이성 (Testability): 각 컴포넌트는 독립적으로 테스트할 수 있어 애플리케이션의 안정성을 높이는 데 기여합니다.
- 유지보수 용이성 (Maintainability): 기능 변경이나 버그 수정 시 특정 컴포넌트만 집중적으로 관리할 수 있어 전체 애플리케이션에 미치는 영향을 최소화합니다.
React는 크게 두 가지 유형의 컴포넌트를 제공합니다: 함수형 컴포넌트와 클래스형 컴포넌트. 이번 글에서는 함수형 컴포넌트에 초점을 맞춰 자세히 알아보겠습니다.
함수형 컴포넌트 (Functional Component)
함수형 컴포넌트는 JavaScript의 일반적인 함수와 매우 유사한 형태를 가집니다. 주요 특징은 다음과 같습니다.
- JavaScript 함수: 함수형 컴포넌트는 단순히 JavaScript 함수로 정의됩니다. ES6의 화살표 함수 (arrow function) 문법을 사용하여 간결하게 표현하는 것이 일반적입니다.
- Props를 인자로 받음: 함수형 컴포넌트는 props (properties)라는 객체를 인자로 받아 부모 컴포넌트로부터 데이터를 전달받습니다. 이 props 객체는 컴포넌트가 렌더링할 UI에 필요한 다양한 정보를 담고 있습니다.
- JSX를 반환: 함수형 컴포넌트는 자신이 렌더링해야 할 UI 구조를 JSX 형태로 반환합니다. 이 JSX는 React에 의해 실제 DOM 요소로 변환되어 화면에 표시됩니다.
- 상태 (State)와 생명주기 (Lifecycle) 부재 (과거): 과거에는 함수형 컴포넌트가 상태 관리나 생명주기 메서드를 가질 수 없는 "stateless" 컴포넌트로 여겨졌습니다. 하지만 Hooks라는 강력한 기능이 React 16.8 버전에 도입되면서 함수형 컴포넌트에서도 상태 관리 및 다양한 부가 기능을 사용할 수 있게 되었습니다.
함수형 컴포넌트 정의 방법:
함수형 컴포넌트는 다음과 같은 두 가지 방식으로 정의할 수 있습니다.
1. 함수 선언식 (Function Declaration):
function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}
2. 화살표 함수 표현식 (Arrow Function Expression):
const Welcome = (props) => {
return <h1>Hello, {props.name}!</h1>;
};
두 가지 방식 모두 동일한 기능을 수행하며, 개발 선호도에 따라 선택하여 사용할 수 있습니다. 최근에는 화살표 함수를 사용하는 것이 더 간결하고 일반적인 스타일로 여겨집니다.
Props 이해하기
Props (Properties)는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 메커니즘입니다. 마치 함수의 인자와 유사하게, 부모 컴포넌트가 자식 컴포넌트를 렌더링할 때 속성 형태로 데이터를 전달하면, 자식 컴포넌트는 이 데이터를 props 객체를 통해 접근하여 자신의 UI를 동적으로 구성할 수 있습니다.
Props 전달 예시:
// 부모 컴포넌트
function App() {
const userName = "Alice";
const message = "Welcome to our website!";
return (
<div>
<Welcome name={userName} /> {/* name이라는 props로 userName 전달 */}
<Greeting text={message} /> {/* text라는 props로 message 전달 */}
</div>
);
}
// 자식 컴포넌트
const Welcome = (props) => {
return <h1>Hello, {props.name}!</h1>; {/* props 객체에서 name 속성 접근 */}
};
const Greeting = (props) => {
return <p>{props.text}</p>; {/* props 객체에서 text 속성 접근 */}
};
위 예시에서 App 컴포넌트는 Welcome 컴포넌트에게 name이라는 이름으로 userName 값을 전달하고, Greeting 컴포넌트에게 text라는 이름으로 message 값을 전달합니다. Welcome과 Greeting 컴포넌트는 전달받은 props를 사용하여 자신의 UI를 렌더링합니다.
Props는 읽기 전용 (Read-Only):
props는 자식 컴포넌트 내에서 읽기 전용입니다. 자식 컴포넌트는 props로 전달받은 값을 변경하려고 시도해서는 안 됩니다. 데이터의 흐름은 항상 부모에서 자식으로 단방향으로 이루어져야 하며, 이를 통해 애플리케이션의 상태 변화를 예측 가능하게 만들고 디버깅을 용이하게 합니다. 자식 컴포넌트에서 부모 컴포넌트의 데이터를 변경해야 하는 경우에는 콜백 함수를 props로 전달하여 부모 컴포넌트에서 상태를 업데이트하는 방식을 사용합니다 (이 내용은 추후 더 자세히 다룰 예정입니다).
간단한 함수형 컴포넌트 만들기
이제 간단한 함수형 컴포넌트를 직접 만들어보고 props를 통해 데이터를 전달하여 UI를 렌더링을 해보겠습니다.
1. src 폴더에 ProfileCard.js 파일을 생성하고 다음 코드를 작성합니다.
import React from 'react';
import './ProfileCard.css'; // (선택 사항) 스타일링을 위한 CSS 파일
const ProfileCard = (props) => {
return (
<div className="profile-card">
<img src={props.avatar} alt={props.name} className="avatar" />
<h3>{props.name}</h3>
<p className="bio">{props.bio}</p>
<p className="followers">Followers: {props.followers}</p>
</div>
);
};
export default ProfileCard;
2. src 폴더에 ProfileCard.css 파일을 생성하고 다음 코드를 작성합니다 (선택 사항).
.profile-card {
border: 1px solid #ccc;
padding: 20px;
margin-bottom: 15px;
border-radius: 5px;
text-align: center;
}
.avatar {
width: 80px;
height: 80px;
border-radius: 50%;
margin-bottom: 10px;
}
.bio {
color: #555;
margin-bottom: 10px;
}
.followers {
font-size: 0.9em;
color: #888;
}
3. src/App.js 파일을 열고 ProfileCard 컴포넌트를 import하여 사용합니다.
import React from 'react';
import ProfileCard from './ProfileCard';
import './App.css';
function App() {
const user1 = {
name: 'John Doe',
avatar: 'https://via.placeholder.com/80/FFC107/000000?Text=JD',
bio: 'Software Engineer passionate about React.',
followers: 150
};
const user2 = {
name: 'Jane Smith',
avatar: 'https://via.placeholder.com/80/4CAF50/FFFFFF?Text=JS',
bio: 'Frontend Developer with a love for UI/UX.',
followers: 210
};
return (
<div className="App">
<header className="App-header">
<h1>User Profiles</h1>
</header>
<main>
<ProfileCard
name={user1.name}
avatar={user1.avatar}
bio={user1.bio}
followers={user1.followers}
/>
<ProfileCard
name={user2.name}
avatar={user2.avatar}
bio={user2.bio}
followers={user2.followers}
/>
</main>
</div>
);
}
export default App;
위 코드에서 App 컴포넌트는 user1과 user2라는 두 개의 사용자 객체를 정의하고, ProfileCard 컴포넌트를 두 번 렌더링하면서 각 사용자 객체의 정보를 props로 전달합니다. ProfileCard 컴포넌트는 전달받은 name, avatar, bio, followers props를 사용하여 사용자 프로필 카드를 화면에 표시합니다.
이번 내용에서는 React 컴포넌트의 기본적인 개념과 그중에서도 핵심적인 역할을 수행하는 함수형 컴포넌트에 대해 자세히 알아보았습니다. 함수형 컴포넌트의 정의 방법, props를 통한 데이터 전달 방식, 그리고 간단한 실습을 통해 함수형 컴포넌트가 UI를 구축하는 기본적인 단위임을 이해하셨으리라 생각합니다.
함수형 컴포넌트는 간결하고 직관적인 코드를 작성하는 데 도움을 주며, Hooks의 도입으로 더욱 강력하고 유연한 기능을 제공하게 되었습니다. 앞으로 React 개발을 진행하면서 함수형 컴포넌트를 자연스럽게 활용하는 것이 중요합니다.
다음 블로그에서는 또 다른 중요한 컴포넌트 유형인 클래스형 컴포넌트 (Class Component)에 대해 알아보는 시간을 갖도록 하겠습니다.
연휴의 한 가운데.. 즐거운 시간 보내세요.
'IT Data 분석' 카테고리의 다른 글
State 관리 기초 (useState 훅): 함수형 컴포넌트에 생명력을 불어넣다 (0) | 2025.05.08 |
---|---|
React 컴포넌트 기초 (클래스형 컴포넌트): 상태 관리와 생명주기 (0) | 2025.05.07 |
JSX 이해: React UI 렌더링의 핵심에 대해 알아볼까요? (0) | 2025.05.04 |
React 시작하기: 웹 개발의 새로운 가능성을 열다 (0) | 2025.05.03 |
AI 에이전트: 더 똑똑한 소프트웨어가 만들어가는 미래 (0) | 2025.05.03 |