[React] Props
개요
Props(Properties)는 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하는 방법입니다. Props는 읽기 전용(Read-Only)으로, 자식 컴포넌트는 전달받은 props를 변경할 수 없습니다.
기본 사용법
Props 전달 (부모)
function App() {
return (
<div>
{/* 속성처럼 값을 전달 */}
<UserCard name="Alice" age={30} job="개발자" />
<UserCard name="Bob" age={25} job="디자이너" />
</div>
);
}
Props 받기 (자식)
// TypeScript: interface로 타입 정의
interface UserCardProps {
name: string;
age: number;
job: string;
}
// 구조분해(destructuring)로 받기 (권장)
function UserCard({ name, age, job }: UserCardProps) {
return (
<div>
<h2>{name}</h2>
<p>나이: {age}</p>
<p>직업: {job}</p>
</div>
);
}
Optional Props와 기본값
interface ButtonProps {
label: string;
color?: string; // ? = 선택사항 (optional)
disabled?: boolean;
}
// 기본값은 = 으로 지정
function Button({ label, color = "blue", disabled = false }: ButtonProps) {
return (
<button
style=
disabled={disabled}
>
{label}
</button>
);
}
// 사용
<Button label="확인" /> // color="blue", disabled=false
<Button label="취소" color="gray" /> // disabled=false
<Button label="삭제" color="red" disabled /> // disabled=true
children Props
컴포넌트 태그 사이에 넣은 내용을 children으로 받습니다.
import { ReactNode } from "react";
interface CardProps {
title: string;
children: ReactNode; // ReactNode = JSX, 문자열, 숫자 등 모든 렌더링 가능한 값
}
function Card({ title, children }: CardProps) {
return (
<div style=>
<h3>{title}</h3>
{children} {/* 태그 사이 내용이 여기에 렌더링됨 */}
</div>
);
}
// 사용
<Card title="사용자 정보">
<p>이름: Alice</p>
<p>이메일: alice@example.com</p>
</Card>
함수 Props (콜백)
부모의 함수를 자식에게 전달해, 자식이 이벤트를 발생시킬 때 부모에게 알립니다.
interface ConfirmDialogProps {
message: string;
onConfirm: () => void; // 인자 없는 함수
onCancel: () => void;
}
function ConfirmDialog({ message, onConfirm, onCancel }: ConfirmDialogProps) {
return (
<div>
<p>{message}</p>
<button onClick={onConfirm}>확인</button>
<button onClick={onCancel}>취소</button>
</div>
);
}
// 사용
function App() {
const handleConfirm = () => {
console.log("확인 클릭");
};
return (
<ConfirmDialog
message="정말 삭제하시겠습니까?"
onConfirm={handleConfirm}
onCancel={() => console.log("취소")}
/>
);
}
Props 전개(Spread)
객체의 모든 속성을 한 번에 전달할 때 사용합니다.
interface UserCardProps {
name: string;
age: number;
job: string;
}
const user: UserCardProps = { name: "Alice", age: 30, job: "개발자" };
// 개별 전달
<UserCard name={user.name} age={user.age} job={user.job} />
// 전개 연산자로 한 번에 전달
<UserCard {...user} />
Props 주의사항
단방향 데이터 흐름
App (부모)
└──> UserCard (자식) Props는 이 방향으로만!
자식은 props를 읽을 수만 있고 변경할 수 없습니다.
function UserCard({ name }: { name: string }) {
// ❌ props 직접 변경 불가
// name = "Bob"; // 오류
return <p>{name}</p>;
}
Props Drilling 문제
props를 여러 단계를 거쳐 깊이 전달하면 코드가 복잡해집니다.
App → Page → Section → Article → Content → Button
(Button에서 필요한 데이터를 5단계 거쳐 전달)
이 문제는 Context API 또는 Zustand 같은 상태 관리 라이브러리로 해결합니다.