컴포넌트(Component)
2025-12-08
컴포넌트는 UI를 재사용 가능한 작은 단위로 나누어 관리하는 요소로, 각각의 컴포넌트가 독립적으로 화면을 구성할 수 있습니다. 이러한 컴포넌트는 입력 값(props)을 받아 그에 맞는 UI 엘리먼트를 반환하는 함수와 같은 역할을 합니다.
앞선 수많은 예제에서 소흘히 넘어갔지만, 확실한 것은 컴포넌트는 JavaScript 함수 입니다. 따라서 모든 컴포넌트는 JavaScript 함수 입니다. 우리는 TypeScript를 사용하지만, 기본적으로 TypeScript는 JavaScript를 확장한 언어이므로, 결과론적으로 JavaScript 함수라 할 수 있습니다.
앞선 예제를 화살표 함수 표현식으로 작성해 보겠습니다.
JSX만 반환하는 경우 중괄호와 return 문을 생략할 수 있습니다. 이는 간결한 바디(concise body)라고 합니다.
함수는 선언과 호출로 구분됩니다. 그리고 컴포넌트는 선언(declaration)과 인스턴스화(instantiation)로 구분됩니다.
React루 구성된 페이지는 컴포넌트 트리(component tree)로 구성됩니다.
함수의 매개변수를 사용해서 외부 값을 받아 올 수 있습니다. React 컴포넌트에서는 이를 Props라고 합니다. Props는 부모 컴포넌트에서 자식 컴포넌트로 정보를 전달하는 수단입니다.
// 부모 컴포넌트
function App() {
const stories = [
{ title: 'React', objectID: 0 },
{ title: 'Redux', objectID: 1 },
];
return (
<div>
<List list={stories} /> {/* props 전달 */}
</div>
);
}
// 자식 컴포넌트
function List(props) {
return (
<ul>
{props.list.map((item) => (
<li key={item.objectID}>{item.title}</li>
))}
</ul>
);
}Props 객체를 구조 분해하여 더 간결하게 사용할 수 있습니다.
컴포넌트의 props는 별도의 타입(또는 인터페이스)으로 정의해 지정합니다.
React.FC(또는 React.FunctionComponent) 사용은 권장되지 않습니다.이벤트 핸들러의 타입도 명확하게 지정합니다.
useRef, useState 등 훅을 사용할 때 generic 타입 매개변수로 명시적으로 타입을 넣을 수 있습니다.
TypeScript에서는 propTypes나 defaultProps 대신 인터페이스(type)와 기본 매개변수를 활용합니다. children을 받는 컴포넌트라면 아래처럼 지정합니다.
JSX.Element로 추론됨(명시 필요 없음)함수는 Next.js에서 사용되는 레이아웃 컴포넌트/) 세그먼트이며, 하위 <children> 세그먼트를 인자로 받아서 화면을 구성children만 추출export default를 사용, 기본 내보내기(default export) 형식으로 제공함Readonly<{ children: React.ReactNode }>로 지정, Readonly<T>는 객체의 속성이 변경될 수 없음(불변 객체)children은 React에서 컴포넌트의 자식 노드를 전달할 때 사용하는 표준 속성, 타입은 React.ReactNode (= 렌더링할 수 있는 모든 React 요소, string, number, null 등) 입니다.
<Layout>내용</Layout>처럼 Layout 컴포넌트가 있을 때, 내용 부분이 자동으로 children으로 전달함수(컴포넌트)는 HTML 마크업을 반환합니다.
<html lang="en"> 태그로 감싸고 있음<body> 엘리먼트에 여러 클래스가 props 형태로 전달되는데, 이는 보통 폰트나 스타일 적용을 위한 것(geistSans.variable, geistMono.variable)children을 그대로 body 안에서 렌더링하여, 이 레이아웃을 사용하는 페이지의 실제 콘텐츠가 해당 위치에 삽입됨Next.js 13+의 app 디렉터리에서 이 레이아웃 파일(app/layout.tsx)은 앱 전체 혹은 특정 라우트 그룹에 공통으로 적용되는 레이아웃 역할을 합니다.
children)를 받아 지정한 HTML 구조에 끼워 넣는 방식으로, 모든 하위 페이지에 일관된 구조를 제공함flex: flexbox 레이아웃을 활성화, 자식 요소들이 플렉스 컨테이너 안에서 정렬, 배치, 크기 조정이 유연하게 동작함
items-center: flexbox에서 자식 요소들을 수직(교차축) 중앙 정렬, flex direction이 기본값(row)이므로 위아래(세로축) 중앙에 위치함justify-center: flexbox에서 자식 요소들을 수평(주축) 중앙 정렬, 좌우(가로축) 기준으로 중앙에 놓임min-h-screen: 컨테이너의 최소 높이(min-height)를 뷰포트 전체 높이(100vh, 즉 화면 전체 높이)로 설정bg-zinc-50: 배경색을 zinc 팔레트의 50단계로 지정, 아주 연한 회색(zinc-50) 계열이며, Tailwind CSS 컬러 스케일의 하나임font-sans: 글꼴을 산세리프 계열로 지정, 시스템에서 산세리프 폰트를 사용하게 되며, 깔끔하고 현대적인 느낌을 줌dark:bg-black: 다크 모드가 활성화된 경우(dark 프리픽스) 배경색을 검정색(black)으로 설정, Light 모드에서는 bg-zinc-50, 다크 모드에선 bg-black이 적용되어 테마를 자연스럽게 전환할 수 있음flex-col: flexbox 방향을 기본 가로(row)에서 세로(column)로 변경, 자식들이 위에서 아래로 쌓임justify-between: flexbox의 주 축(main axis, 여기서는 세로축)에서 자식 요소들 사이를 가능한 멀리 떨어뜨려 배치w-full: 요소의 가로 너비를 부모 요소 기준으로 100%로 설정max-w-3xl: 최대 너비를 Tailwind에서 지정한 3xl(즉, 약 48rem)로 제한, 너무 넓어지지 않게 함py-32: 위아래(padding-top, padding-bottom)에 각각 32단계(preset, 약 8rem)의 내부 여백 추가px-16: 좌우(padding-left, padding-right)에 각각 16단계(약 4rem)의 내부 여백 추가bg-white: 배경색을 흰색으로 지정dark:bg-black: 다크 모드에서는 배경색을 검정색으로 변경sm:items-start: 작은(sm, 약 640px 이상) 화면에서는 flexbox의 교차축(여기서는 가로축) 기준으로 자식 요소들을 시작점(왼쪽) 정렬
sm: 40rem (640px), @media (width >= 40rem) { … }md: 48rem (768px), @media (width >= 48rem) { … }lg: 64rem (1024px), @media (width >= 64rem) { … }xl: 80rem (1280px), @media (width >= 80rem) { … }2xl: 96rem (1536px), @media (width >= 96rem) { … }<Image> 태그를 사용, 이미지를 렌더링할 때 사용