1. 컴포넌트 (Components) 🧩
컴포넌트의 개념
- UI를 독립적이고 재사용 가능한 조각으로 분리한 것
- 각 컴포넌트는 자체 로직과 렌더링 방식을 가짐
- JavaScript 함수나 클래스로 구현됨
함수형 컴포넌트
- 간결하고 이해하기 쉬운 문법
- React 16.8 이후 Hooks를 통해 상태 관리 가능
- 최신 React 개발에서 권장되는 방식
function Welcome(props) {
return <h1>안녕하세요, {props.name}님!</h1>;
}
클래스형 컴포넌트
- React.Component를 상속받아 구현
- render() 메서드 필수
- 생명주기 메서드 활용 가능
class Welcome extends React.Component {
render() {
return <h1>안녕하세요, {this.props.name}님!</h1>;
}
}
컴포넌트 네이밍과 구조
- 파스칼 케이스(PascalCase) 사용 필수
- 단일 루트 요소 반환 (Fragment 사용 가능)
- 컴포넌트 파일 구조화 방법 (폴더별, 기능별)
2. Props (Properties) 🔄
Props의 개념
- 컴포넌트 간 데이터 전달 메커니즘
- HTML 속성과 유사하게 작동
- 부모 컴포넌트에서 자식 컴포넌트로 단방향 데이터 흐름
Props 사용법
- 객체 형태로 전달됨
- 구조 분해 할당으로 간결하게 사용 가능
// Props 전달
<UserProfile name="민영" age={25} isAdmin={true} />
// Props 받기 (구조 분해 할당)
function UserProfile({ name, age, isAdmin }) {
return (
<div>
<h2>{name}</h2>
<p>나이: {age}</p>
{isAdmin && <p>관리자입니다</p>}
</div>
);
}
Props 특성
- 읽기 전용(불변)으로 컴포넌트 내에서 수정 불가
- 모든 React 컴포넌트는 props에 대해 순수 함수처럼 동작해야 함
- 객체, 배열, 함수도 props로 전달 가능
defaultProps
function Button({ text = "클릭" }) {
return <button>{text}</button>;
}
// 또는
Button.defaultProps = {
text: "클릭"
};
PropTypes
- props 타입 검증 시스템
- 개발 모드에서만 작동
import PropTypes from 'prop-types';
function User({ name, age }) {
return <p>{name}님은 {age}세입니다</p>;
}
User.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
};
3. 컴포넌트 합성과 추출 🔧
컴포넌트 합성
- 여러 컴포넌트를 조합하여 복잡한 UI 구성
- 컴포넌트 중첩을 통한 계층 구조 형성
function App() {
return (
<div>
<Header />
<MainContent>
<Sidebar />
<Articles />
</MainContent>
<Footer />
</div>
);
}
컴포넌트 추출
- 큰 컴포넌트를 작은 단위로 분리
- 재사용성과 테스트 용이성 향상
- 관심사 분리 원칙 적용
4. Props 활용 패턴 ⚙️
children prop
function Card({ children, title }) {
return (
<div className="card">
<h2>{title}</h2>
<div>{children}</div>
</div>
);
}
// 사용
<Card title="알림">
<p>새로운 메시지가 있습니다.</p>
</Card>
조건부 렌더링
function Message({ isLoggedIn, username }) {
return (
<div>
{isLoggedIn
? <h1>환영합니다, {username}님!</h1>
: <h1>로그인해주세요</h1>}
</div>
);
}
리스트 렌더링
function TodoList({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
이벤트 핸들러 전달
- 함수를 props로 전달하여 자식 컴포넌트에서 부모 상태 변경
function Parent() {
const [count, setCount] = useState(0);
const handleIncrement = () => setCount(count + 1);
return <Child onIncrement={handleIncrement} count={count} />;
}
function Child({ onIncrement, count }) {
return (
<div>
<p>카운트: {count}</p>
<button onClick={onIncrement}>증가</button>
</div>
);
}
스프레드 연산자로 props 전달
function ParentComponent() {
const userProps = {
name: "민영",
age: 25,
location: "서울"
};
return <UserInfo {...userProps} />;
}
5. 컴포넌트와 Props 모범 사례 🌟
- 단일 책임 원칙 준수 (컴포넌트는 한 가지 일만)
- props 이름은 명확하고 일관되게 작성
- 불필요한 props 드릴링 피하기
- 컴포넌트 재사용성 극대화
- 적절한 컴포넌트 크기 유지 (너무 크지 않게)