리액트 컴포넌트의 기본 개념 완전 정복하기
여러분, 리액트 입문하려고 검색하다가
"컴포넌트"라는 단어에 자꾸 막히신 적 있지 않으셨나요?
도대체 그게 뭐길래 이렇게 중요할까요?
안녕하세요,
이번 글에서는 리액트의 핵심 개념 중 하나인 컴포넌트(Component)에 대해 아주 쉽게, 그리고 직관적으로 설명해 드릴 거예요.
함수형 vs 클래스형? Props와 State는 또 뭔데? 이런 의문들, 여기서 전부 해결해 드릴게요!
지금부터 저와 함께 찬찬히, 하나씩 배워봅시다. 😄
목차
1. 컴포넌트란 무엇인가요? 🤔
리액트에서 컴포넌트(Component)는 웹 페이지를 이루는 가장 작은 단위입니다.
우리가 눈으로 보는 버튼, 텍스트, 이미지, 카드 같은 것들이 바로 이 컴포넌트들로 구성돼 있어요.
정확히 말하면, 하나의 UI 요소를 독립적인 모듈로 나누어 관리할 수 있게 해주는 것이 바로 컴포넌트입니다.
🧠 왜 컴포넌트가 중요할까요?
- 재사용성 향상:
- 한 번 만든 컴포넌트를 다른 곳에서도 재사용할 수 있어요.
- 유지보수가 쉬워짐:
- 각 컴포넌트는 독립적으로 동작하므로 수정이 편리해요.
- 테스트 용이:
- 독립적인 단위라서 테스트 작성도 수월하답니다.
컴포넌트 예시: 쇼핑몰의 상품 카드
예를 들어 볼까요?
쇼핑몰 사이트를 떠올려보세요. 상품 리스트 화면에는 여러 개의 카드가 나열되어 있을 거예요.
각 카드에는 상품명, 이미지, 가격, 찜 버튼 같은 것들이 들어 있죠. 이걸 하나의 컴포넌트로 만들 수 있어요!
이렇게 하나의 UI 단위를 컴포넌트로 만들어 놓으면, 이후에 다른 페이지나 서비스에서도 복붙처럼 재활용할 수 있어서 정말 유용해요!
📋 컴포넌트란 이런 것!
구분 | 내용 |
---|---|
정의 | UI를 구성하는 독립적이고 재사용 가능한 단위 |
장점 | 재사용성, 유지보수 용이, 테스트 편리 |
실전 예시 | 상품 카드, 버튼, 입력 폼 등 다양한 UI 구성 |
여기까지가 리액트 컴포넌트의 정체에 대한 기본 설명이었어요!
다음 챕터에서는 실전 코드 예제를 통해 컴포넌트를 직접 만들어보며 더 깊이 이해해 볼게요. 😊
2. 함수형 컴포넌트 실전 예제 🧩
리액트에서 가장 많이 쓰이는 컴포넌트 형태는 바로 함수형 컴포넌트입니다.
ES6 이후 등장했고, 특히 React Hooks가 추가되면서 완전 대세로 자리잡았죠!
🧪 간단한 상품 카드 예제
한 번 코드를 같이 볼까요?
아래는 상품명을 보여주고 좋아요(Like) 버튼이 있는 간단한 컴포넌트입니다.
import React, { useState } from 'react';
function ProductCard({ name, price }) {
const [liked, setLiked] = useState(false);
return (
<div>
<h3>{name}</h3>
<p>Price: ${price}</p>
<button onClick={() => setLiked(!liked)}>
{liked ? 'Unlike' : 'Like'}
</button>
</div>
);
}
export default ProductCard;
🧠 코드 해석
-
useState
를 통해 liked라는 상태값을 생성 - 버튼 클릭 시
setLiked
를 호출하여 상태를 반전시킴 - 상태가 바뀌면 리렌더링되어
'Like'
또는'Unlike'
가 즉시 반영됨
정말 신기하지 않나요? 단 몇 줄의 코드만으로 사용자 반응에 따라 UI가 바뀌다니...
이게 바로 리액트 함수형 컴포넌트의 매력이에요!
📌 함수형 컴포넌트 특징 정리
항목 | 설명 |
---|---|
형태 | 일반 자바스크립트 함수 형태 |
상태 관리 | useState 훅 사용 |
라이프사이클 | useEffect 등 훅으로 처리 |
장점 | 가볍고 읽기 쉬움, 훅으로 다양한 기능 확장 가능 |
이제 함수형 컴포넌트가 어떤 식으로 동작하는지 감이 좀 오셨죠? 😄
다음 단계에서는 클래스형 컴포넌트와 비교해 보면서 차이를 더 분명하게 알아볼 거예요.
3. 클래스형 컴포넌트도 아직 유효할까요? 🏛
요즘 리액트 개발자들 사이에선 함수형 컴포넌트가 대세지만, 클래스형 컴포넌트도 여전히 존재합니다.
특히 옛날 코드나 레거시 프로젝트를 다룰 땐 꼭 알아둬야 해요.
React 16.8 이전까지는 클래스형 컴포넌트가 기본이었거든요.
📦 클래스형 컴포넌트 예제
아까 함수형으로 만들었던 ProductCard를 이번엔 클래스 기반으로 다시 만들어볼게요.
import { Component } from 'react';
class ProductCard extends Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
toggleLike = () => {
this.setState({ liked: !this.state.liked });
};
render() {
return (
<div>
<h3>{this.props.name}</h3>
<p>Price: ${this.props.price}</p>
<button onClick={this.toggleLike}>
{this.state.liked ? 'Unlike' : 'Like'}
</button>
</div>
);
}
}
export default ProductCard;
🧠 클래스형 방식 요점 정리
-
constructor()
에서 상태this.state
초기화 - 이벤트 핸들러는 보통 화살표 함수(
=>
)로 바인딩 처리 - UI 출력은
render()
메서드 안에서 처리
🆚 함수형 vs 클래스형 비교
구분 | 함수형 컴포넌트 | 클래스형 컴포넌트 |
---|---|---|
문법 | 자바스크립트 함수 | ES6 클래스 |
상태 관리 | useState |
this.state + setState() |
라이프사이클 | useEffect |
componentDidMount 등 |
사용 추천 | 현대 리액트 개발 전반 | 레거시 유지보수나 학습용 |
정리하자면,
클래스형 컴포넌트는 여전히 중요하지만,
현재 실무에서는 함수형이 거의 대부분이니 초보자분들은 함수형 중심으로 익히는 게 좋아요!
4. JSX와 컴포넌트 구조 🧬
리액트 컴포넌트를 제대로 이해하려면, JSX 문법과 컴포넌트의 구조에 대한 이해는 필수예요.
JSX는 JavaScript 내부에서 HTML을 작성할 수 있게 도와주는 리액트 전용 문법이에요.
🔤 JSX란?
JSX는 JavaScript XML의 줄임말로, XML(HTML)과 비슷한 문법을 JavaScript 코드 안에 바로 작성할 수 있게 해줘요.
function WelcomeMessage() {
return <h1>Welcome to My Website!</h1>;
}
이처럼 JSX는 HTML처럼 생겼지만, 실제론 JavaScript 코드라는 점!
그래서 문법적으로도 JS 규칙을 따라야 해요.
예를 들어 class는 className
으로 써야 하죠.
🔗 Props로 데이터 전달하기
컴포넌트끼리 데이터를 전달할 땐 Props(속성)를 사용합니다.
부모 컴포넌트가 자식 컴포넌트에 값을 전달하는 역할이죠!
// 부모 컴포넌트
function App() {
return <ProductCard name="Laptop" price={999} />;
}
// 자식 컴포넌트
function ProductCard(props) {
return (
<div>
<h3>{props.name}</h3>
<p>Price: ${props.price}</p>
</div>
);
}
여기서 중요한 점은 Props는 읽기 전용이라는 거예요. 컴포넌트 안에서 직접 수정할 수는 없어요.
📈 State로 동적인 값 관리하기
Props는 부모 → 자식으로 전달하는 고정값이라면, State는 컴포넌트 자체에서 변화하는 값이에요.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
이 컴포넌트는 클릭할 때마다 상태(count)가 변하면서 UI가 즉각 반응해요.
이게 바로 리액트의 진짜 매력이죠!
📌 JSX & 컴포넌트 구조 요약
개념 | 설명 |
---|---|
JSX | JS 안에 HTML처럼 작성할 수 있는 리액트 문법 |
Props | 부모 컴포넌트가 자식에게 전달하는 읽기 전용 값 |
State | 컴포넌트 내부에서 관리되는 동적 데이터 |
여기까지가 JSX와 컴포넌트의 기본 구조였어요! 이제 마지막으로 React Hooks를 활용해 라이프사이클까지 정리해 볼게요. 💫
6. React Hooks로 라이프사이클 관리하기 🔁
React에서 컴포넌트는 생성 → 업데이트 → 소멸이라는 생명주기(Lifecycle)를 갖습니다.
클래스형 컴포넌트에서는 이 생명주기를
componentDidMount
, componentDidUpdate
, componentWillUnmount
등 메서드로 관리했는데요.
함수형 컴포넌트에서는 useEffect라는 Hook 하나로 라이프사이클을 모두 컨트롤할 수 있어요!
⏱ 라이프사이클이란?
- Mount: 컴포넌트가 처음 렌더링될 때
- Update: 상태나 Props가 바뀌어 다시 렌더링될 때
- Unmount: 컴포넌트가 화면에서 사라질 때
💡 useEffect 기본 사용법
import { useState, useEffect } from 'react';
function Timer() {
const [time, setTime] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setTime(prev => prev + 1);
}, 1000);
return () => clearInterval(interval); // 언마운트 시 정리
}, []);
return <p>경과 시간: {time}초</p>;
}
위 예제에서는 setInterval
을 이용해서 1초마다 time
을 증가시키고 있고요.return
안의 함수는 컴포넌트가 사라질 때 실행돼서 타이머를 정리해줍니다.
이걸 정리(clean-up) 함수라고 불러요!
🧭 useEffect 두 번째 인자
패턴 | 설명 |
---|---|
useEffect(fn, []) |
Mount 시 한 번만 실행됨 |
useEffect(fn, [state]) |
해당 값이 변경될 때마다 실행됨 |
useEffect(fn) |
모든 리렌더링마다 실행됨 |
이렇게 useEffect
는 조건에 따라 다양한 방식으로 리액트 생명주기를 제어할 수 있어서 정말 유용해요!
✅ 정리: 리액트 훅과 라이프사이클
- 함수형 컴포넌트의 생명주기 처리는
useEffect
하나로 가능! -
useEffect(fn, [])
은 컴포넌트 마운트 시 한 번만 실행됨 -
return
문 안에 정리(clean-up) 코드를 작성해 언마운트 처리
이제 여러분은 컴포넌트의 생성과 파괴까지 제어할 수 있는 리액트 고수가 되어가고 있어요! 👏
다음은 마지막으로 전체 내용을 요약하며 마무리해볼게요.
🎯 컴포넌트 개념, 이제 어렵지 않죠?
여기까지 따라오신 여러분, 정말 대단하세요! 👏
처음엔 조금 낯설고 어렵게 느껴졌을지 몰라도, 지금쯤이면 리액트 컴포넌트의 구조와 사용법이 꽤 익숙해졌을 거예요.
다시 한번 핵심만 정리해볼게요.
- 컴포넌트는 UI의 최소 단위이며, 재사용성과 유지보수성을 높여줍니다.
- 함수형 컴포넌트가 요즘 대세이며,
Hooks
를 통해 상태와 생명주기를 제어할 수 있어요. - Props는 외부에서 받는 값, State는 내부에서 변화하는 값이에요.
- JSX 문법을 통해 JavaScript 안에서 HTML처럼 코드를 작성할 수 있어요.
이제 여러분은 리액트 컴포넌트를 제대로 이해한 거예요!
다음 단계로 넘어가기 전에, 간단한 프로젝트나 미니 앱을 직접 만들어보면서 복습해보는 걸 추천드려요.
실습이 최고의 선생님입니다! 😉
'React' 카테고리의 다른 글
styled-components로 리액트 스타일링하기 (2) | 2025.04.05 |
---|---|
React에서 CSS 적용하기: 3가지 방법과 활용법 (0) | 2025.04.04 |
React로 UI 만들기 (0) | 2025.04.03 |
React의 실행 과정 자세히 살펴보기 (0) | 2025.04.02 |
2025년 Vite로 빠르게 React 프로젝트 만들기! (JavaScript 버전) (0) | 2025.03.31 |