Component
리액트(React)에서 UI를 구성하는 기본 단위
→ 레고 블록처럼, 여러 개의 작은 컴포넌트를 조합하여 복잡한 UI를 만들 수 있음
→ 컴포넌트는 재사용 가능해야 함 (한 번 만든 컴포넌트는 다양한 곳에서 반복적으로 사용할 수 있어야 함)
- 재사용성 : 동일한 UI 요소를 여러 곳에서 사용할 수 있어 코드 중복을 줄임
- 유지보수 용이 : 코드가 잘 조직되어 있어 변경 및 수정 용이
- 가독성 증가 : 역할별로 컴포너트를 분리하면 전체 코드의 가독성이 높아짐
컴포넌트의 유형
함수형 컴포넌트 (Functional Component)
- ES6 함수 형태로 작성되며, 간결하고 가독성이 좋음
- React Hooks(useState, useEffect 등)를 사용하여 상태 및 생명주기 기능을 관리 가능
- 최근 리액트 버전에서는 함수형 컴포넌트가 주로 사용됨
import React, { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
};
export default Counter;
클래스형 컴포넌트 (Class Component)
- ES6 클래스 문법을 사용하며, this.state와 this.setState()로 상태 관리
- React 생명주기 메서드(componentDidMount, componentDidUpdate, componentWillUnmount 등)를 사용 가능
- 함수형 컴포넌트와 Hook가 등장하면서 점사 사용이 줄어들고 있음
import React, { Component } from "react";
class Counter extends Component {
state = { count: 0 };
handleIncrease = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>현재 카운트: {this.state.count}</p>
<button onClick={this.handleIncrease}>증가</button>
</div>
);
}
}
export default Counter;
Props (Properties)
부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달할 때 사용하는 읽기 전용 값(속성)
→ Props를 활용하여 재사용 가능한 컴포넌트를 만들 수 있음
const Greeting = ({ name }) => {
return <h1>안녕하세요, {name}님!</h1>;
};
// 사용 예시
<Greeting name="수빈" />
name이 props로 전달되어, 이름을 넣어 사용할 수 있음
컴포넌트 분리 및 설계 방법
역할별 분리
- 하나의 컴포넌트는 하나의 역할만 수행하도록 만들어야 함
예:
할 일 목록(TodoList), 할 일 항목(TodoItem)은 별도의 컴포넌트로 분리하는 것이 좋음
const TodoItem = ({ task }) => {
return <li>{task}</li>;
};
const TodoList = () => {
const tasks = ["운동하기", "공부하기", "요리하기"];
return (
<ul>
{tasks.map((task, index) => (
<TodoItem key={index} task={task} />
))}
</ul>
);
};
TodoItem : 개별 항목을 표시
TodoList : 전체 목록을 관리
재사용성 고려
- 공통 요소(예: 버튼, 입력 필드)는 독립적인 컴포넌트로 만들어야 여러 곳에서 사용 가능
const Button = ({ text, onClick }) => {
return <button onClick={onClick}>{text}</button>;
};
<Button text="클릭하세요" onClick={() => alert("버튼 클릭!")} />;
큰 컴포넌트 쪼개기
많은 기능을 가진 거대한 컴포넌트는 유지보수가 어렵기 때문에, 작은 컴포넌트로 나누는 것이 좋음
// 잘못된 예시 (모든 기능을 한 컴포넌트에서 처리)
const TodoApp = () => {
const [tasks, setTasks] = useState(["운동하기", "공부하기"]);
const addTask = (task) => setTasks([...tasks, task]);
return (
<div>
<input type="text" placeholder="할 일 입력" />
<button onClick={() => addTask("새로운 할 일")}>추가</button>
<ul>
{tasks.map((task, index) => (
<li key={index}>{task}</li>
))}
</ul>
</div>
);
};
vs.
// 좋은 예시 (역할별로 분리)
const TodoInput = ({ onAdd }) => {
return (
<div>
<input type="text" placeholder="할 일 입력" />
<button onClick={() => onAdd("새로운 할 일")}>추가</button>
</div>
);
};
const TodoList = ({ tasks }) => {
return (
<ul>
{tasks.map((task, index) => (
<li key={index}>{task}</li>
))}
</ul>
);
};
const TodoApp = () => {
const [tasks, setTasks] = useState(["운동하기", "공부하기"]);
const addTask = (task) => setTasks([...tasks, task]);
return (
<div>
<TodoInput onAdd={addTask} />
<TodoList tasks={tasks} />
</div>
);
};
TodoInput(입력 기능)과 TodoList(목록 표시)를 분리하면 코드가 깔끔해지고 유지보수가 쉬워짐
'React > ReactThreeFiber' 카테고리의 다른 글
useEffect & useRef (2) | 2025.03.14 |
---|---|
React로 사고하기 (1) | 2025.03.13 |
Event Handling (0) | 2025.03.12 |
State (1) | 2025.03.12 |
JSX (1) | 2025.03.11 |