React Component

쏘뽀끼·2024년 7월 29일

react

목록 보기
7/25

함수형 컴포넌트

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버전에 추가된 '리액트 훅'으로 인해서 사용성의 대변화를 겪게 된다.

16.8이전

함수형 컴포넌트 사용하기 불편

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 일부가 자체적으로 복잡한 경우에는 별도로 컴포넌트를 만드는 게 좋다.

참고로 컴포넌트는 작명시 첫 글자는 대문자로 작성하는 게 관례적이다.

0개의 댓글