export type TProps = {
name: string;
};
function Component(props: TProps) {
return (
<>
<h1> Hello, {props.name}</h1>
</>
);
}
import { ReactNode } from "react";
import React from "react";
import { TProps } from "./Compoent1";
class Welcome extends React.Component<TProps> {
render(): ReactNode {
return <h1>Hello, {this.props.name}</h1>;
}
}
보면 알지만, 함수형 컴포넌트가 훨씬 간단하고 직관적이다.
함수형 컴포넌트는 리액트 16.8버전에 추가된 '리액트 훅'으로 인해서 사용성의 대변화를 겪게 된다.
함수형 컴포넌트 사용하기 불편
새롭게 추가된 '리액트 훅'으로 인해 더 이상 클래스 컴포넌트를 사용하는 게 비효율적인 시대로 변화
하나의 컴포넌트는 다른 컴포넌트에 가서 자신을 출력(사용)할 수 있다.
또한 여러번 사용할 수 있다.
버튼, 폼, 다이얼로그 태그처럼 컴포넌트를 사용할 수 있다.
Welcome을 여러번 렌더링 하는 App 컴포넌트
//welcome Component
import { TProps } from "./Compoent1";
const Welcome = (props: TProps) => {
return <h1>Hello, {props.name}</h1>;
};
export default Welcome;
이 welcome 컴포넌트를 App에서 사용하자
//App
import Welcome from "../components/ComponentEx/Welcome";
const App = () => {
return (
<>
<Welcome name="Sara" />//Hello, Sara
<Welcome name="Cahal" />//Hello, Cahal
<Welcome name="Edite" />//Hello, Edite
</>
);
};
export default ComponentPage;
컴포넌트를 세분화 해서 사용할 수 있다.
하나의 긴 코드를 각각 세분화해 각각의 컴포넌트로 만들어 분리가 가능하다!
이렇게 되면 재사용성도 높아지고 직관적으로 코드를 읽을 수 있는 장점이 있다.
function Comment(props) {
const formatDate = (date: Date) => {
return date.toLocaleDateString();
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
이렇게 길이가 긴 Comment라는 컴포넌트가 있다.
이중 Avatar부분을 분리해서 하나의 컴포넌트로 만들어 보겠다.
import { TCommentProps } from "./Comment";
const Avatar = (props: TCommentProps) => {
return (
<>
<img
className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
</>
);
};
export default Avatar;
그럼
function Comment(props) {
const formatDate = (date: Date) => {
return date.toLocaleDateString();
return (
<div className="Comment">
<div className="UserInfo">
<Avatar author={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
코드가 간결해진 걸 볼 수 있다.
여기서 UserInfo부분을 컴포넌트로 분리시켜보자
import Avatar from "./Avatar";
import { TCommentProps } from "./Comment";
const UserInfo = (props: TCommentProps) => {
return (
<>
<div className="UserInfo">
<Avatar author={props.author} />
<div className="UserInfo-name">{props.author.name}</div>
</div>
</>
);
};
export default UserInfo;
그럼
import UserInfo from "./UserInfo";
export type TCommentProps = {
author: {
name?: string;
avatarUrl?: string;
};
text?: string;
date?: Date;
};
function Comment(props: TCommentProps) {
const formatDate = (date: Date) => {
return date.toLocaleDateString();
};
return (
<div className="Comment">
<UserInfo author={props.author} />
<div className="Comment-text">{props.text}</div>
<div className="Comment-date">
{props.date ? formatDate(props.date) : ""}
</div>
</div>
);
}
export default Comment;
코드가 더 간결해진걸 확인 할 수 있다.
이렇게 세분화해야 재사용 가능한 컴포넌트를 만들 수 있다.
만약 다른 페이지에서 UserInfo 부분만 필요할 수 있다.
그럼 UserInfo만 import해서 사용할 수 있다.
그러나 세분화 하지 않으면 같은 코드를 다시 작성해야 하는 번거로움이 생길 수 있다.
UI일부가 여러 번 사용되거나, UI 일부가 자체적으로 복잡한 경우에는 별도로 컴포넌트를 만드는 게 좋다.
참고로 컴포넌트는 작명시 첫 글자는 대문자로 작성하는 게 관례적이다.