📌 React 컴포넌트
: 사용자 인터페이스(UI)를 구성하는 부품
- 재사용 매커니즘(클래스 또는 함수)를 사용하여 리액트 요소를 반환하는 것
- 컴포넌트 명
- 웹 컴포넌트: 케밥 케이스(kebab-case)
- 리액트 컴포넌트: 파스칼 케이스(CamelCase)
✅ 컴포넌트 속성(Props)
: 컴포넌트에 전달되는 입력값
- props는 항상 객체, 읽기 전용
- 컴포넌트를 다양하게 재사용 할 수 있게 한다.
- 컴포넌트에 전달된 속성에 따라 마크업을 동적으로 생성 가능
함수형 컴포넌트 props
- props를 매개변수와 인자로 받음
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
클래스형 컴포넌트 props
- props를 this로 접근
class NumberList extends React.Component {
render() {
// 컴포넌트 속성 접근
// props: 읽기 전용
console.log(this.props);
// 동적으로 컴포넌트 생성
const children = Array(this.props.count).fill(null).map((_, index) =>
h('li', {}, `${index + 1}01`)
);
// 리액트 요소 반환
return React.createElement(
"ul",
{ className: "architectures", lang: "en", id: this.props.id },
children
);
}
}
// 매개변수로 props 전달
const list1 = React.createElement(NumberList, { id: "list-1", count: 3 });
const list2 = h(NumberList, { id: "list-2", count: 5 });
const list3 = h(NumberList, { id: "list-3", count: 11 });
✅ 컴포넌트 타입(Types)
1. 함수형 컴포넌트 (Functional Component)
- props를 인수 받음
1️⃣ 함수 컴포넌트 생성
function 컴포넌트명(props) {
// 리액트 요소 반환
return
}
function ArchitectureList(props) {
// 컴포넌트 속성 설정
const { lang, children } = props;
// 리액트 요소 반환
return React.createElement(
'ul',
{ className: 'architectures', lang },
children
);
}
개별 컴포넌트 생성
import { createElement as h } from "https://esm.sh/react";
function Avatar({ name, photo, status = "offline", size = 64 }) {
// 프로필 상태 변경
let iconPath = "";
let statusMessage = '';
switch (status) {
default:
case "offline":
iconPath = "/icons/status-offline.svg";
statusMessage = '오프라인';
break;
case "online":
iconPath = "/icons/status-online.svg";
statusMessage = '온라인';
break;
}
const label = `${name} (${statusMessage})`;
return h(
"figure",
{
className: "Avatar",
"aria-label": label,
title: label
},
h("img", {
src: `/faces/${photo}`,
alt: name,
width: size,
height: size,
})
);
}
export default Avatar;
2️⃣ 컴포넌트 사용
React.createElement(컴포넌트 참조)
import React from 'https://esm.sh/react';
import { createRoot } from 'https://esm.sh/react-dom';
import AvatarListPage from './pages/AvatarPageList.js';
const container = document.getElementById('react-app');
createRoot(container).render(
React.createElement(AvatarListPage)
);
개별 컴포넌트를 모은 컴포넌트
import { createElement as h } from 'https://esm.sh/react';
import Avatar from '../components/Avatar.js';
function AvatarListPage() {
return h(
'ul',
{
className: 'AvatarList',
},
h('li', null, h(Avatar, { name: '에이', photo: 'man-02.jpg', status: 'online' })),
h('li', null, h(Avatar, { name: '비', photo: 'man-04.jpg', status: 'away' }))
);
}
export default AvatarListPage;
3️⃣ 렌더링
import React from 'https://esm.sh/react';
import { createRoot } from 'https://esm.sh/react-dom';
import AvatarListPage from './pages/AvatarPageList.js';
// 리액트 앱을 렌더링 할 DOM 요소 참조
const container = document.getElementById('react-app');
// DOM 요소가 존재한다면
if (container) {
createRoot(container).render(
React.createElement(AvatarListPage)
);
} else {
console.warn('문서에 "#app" 요소가 존재하지 않습니다.');
}
2. 클래스형 컴포넌트 (Class Component)
1️⃣ 클래스 컴포넌트 생성
- 생성자는 사용하지 않아도 됨
class 컴포넌트명 extends React.Component {
// 렌더링
render() {
// 리액트 요소 반환
return
}
}
class ArchitecturesList extends React.Component {
// 렌더 메서드
render() {
// 리액트 요소 반환
return React.createElement(
"ul",
{ className: "architectures", lang: "en" },
h('li', { className: 'item' }, 101),
h('li', { className: 'item' }, 201),
);
}
}
개별 컴포넌트 생성
import { createElement as h, Component } from 'https://esm.sh/react';
class ArchitectureItem extends Component {
render() {
const { id, title } = this.props;
return h('li',
{
key: id,
className: 'item',
},
h('img',
{
src: `/architectures/architecture-${id}.jpg`,
alt: '',
}),
h('span',
{ className: 'content'},
title
)
);
}
}
export default ArchitectureItem;
2️⃣ 컴포넌트 사용
React.createElement(컴포넌트 참조)
개별 컴포넌트를 모은 컴포넌트
import React from 'https://esm.sh/react';
class ArchitectureList extends React.Component {
render() {
const { lang, children } = this.props;
return React.createElement(
'ul',
{ className: 'architectures', lang },
children
);
}
}
export default ArchitectureList;
3️⃣ 렌더링
import React from 'https://esm.sh/react';
import { createRoot } from 'https://esm.sh/react-dom';
import AvatarListPage from './pages/AvatarPageList.js';
const container = document.getElementById('react-app');
// 렌더링
if (container) {
createRoot(container).render(
React.createElement(ArchitectureListPage)
);
} else {
console.warn('문서에 "#app" 요소가 존재하지 않습니다.');
}