컴포넌트 이해하기

김동현·2023년 8월 7일
0

리액트 컴포넌트

리액트는 HTML5의 각 태그에 대응하는 리액트 컴포넌트를 제공한다.

const h1 = <h1>Hello</h1>

이를 React.createElement 함수로 표현하면 다음과 같다.

const h1 = React.createElement('h1', null, "Hello")

리액트 컴포넌트의 이름은 소문자로 시작한다.

리액트가 컴포넌트를 이런 방식으로 설계한 것은 HTML5에 해당하는 컴포넌트 이름을 일일이 임포트하지 않게 하려는 의도이다.

import {h1, h2, div} from 'react'

사용자 컴포넌트

아래의 JSXVirtualDOM 은 사용자 컴포넌트이다.
리액트 컴포넌트 또는 다른 사용자 컴포넌트의 조합으로 이루어진다.

const JSXVirtualDOM = (
  <ul>
    <li>
      <a href="https://www.google.com" target="_blank">
        <p>구글로 이동</p>
      </a>
    </li>
  </ul>
)

앞의 포스팅에서 React.createElement 의 함수 선언문을 봤었다.
다시 가져와보자.

function createElement<P extends {}>(
  type: FunctionComponent<P> | ComponentClass<P> | string,
   props?: Attributes & P | null,
   ...children: ReactNode[]): ReactElement<P>;

매개변수 type 의 타입이 string 일 수도 있지만 FunctionComponent<P> 또는ComponentClass<P> 타입일 수도 있다.

함수형 컴포넌트의 타입이 FunctionComponent<P> 이고 클래스 컴포넌트의 타입이 ComponentClass<P> 이다.

클래스 컴포넌트

리액트에서 클래스 컴포넌트는 반드시 react패키지가 제공하는 Component 클래스를 상속해야 한다.
그리고 render 라는 이름의 메서드를 포함해야한다.
render 메서드는 React.ReactNode 타입을 리턴해야 한다.

// 기본형
import React, {Component} from 'react'
class ClassComponent extends Component {
  render(): React.ReactNode {
    return null
  }
}

// JSX형
import React, {Component} from 'react'
class ClassComponent extends Component {
  render(): React.ReactNode {
    return (
      <ul>
        <li>
          <a href="https://www.google.com" target="_blank">
            <p>구글로 이동</p>
          </a>
        </li>
      </ul>
    )
  }
}

클래스 컴포넌트에 속성 구현하기

import React, {Component} from 'react'

type ClassComponentProps = {
  href: string;
  text: string;
}

class ClassComponent extends Component<ClassComponentProps> {
  render(): React.ReactNode {
    const {href, text} = this.props
    return (
      <ul>
        <li>
          <a href={href} target="_blank">
            <p>{text}</p>
          </a>
        </li>
      </ul>
    )
  }
}
// 컴포넌트 호출
<ClassComponent href='https://google.com' text="구글로 이동" />

함수형 컴포넌트

앞의 클래스 컴포넌트는 render 만 의미가 있고 나머지 코드는 render 메서드를 구현할 수 있게 하는 프로그래밍 언어의 문법을 갖추는 코드일 뿐이다.
리액트 개발팀은 이에 주목하여 클래스 컴포넌트의 render 메서드 부분을 간단히 함수로 만들 수 있게 했고, 이런 방식을 함수형 컴포넌트라고 이름 붙였다.

타입스크립트에서 함수를 만드는 구문은 2가지이다.
하나는 function 키워드로 만드는 함수이고 나머지 하나는 화살표 함수이다.

function 키워드로 만드는 함수

function FunctionComponent() {
  return <h1>function component</h1>
}

화살표 함수

const FunctionComponent = () => {
  return <h1>function component</h1>
}

타입스크립트 import type 구문
다음 코드에서 FC 타입은 import type 구문을 사용했지만, Component 클래스는 단순히 import 구문을 사용하고 있다.

import type {FC} from 'react'
import {Component} from 'react'

타입스크립트에서 타입은 컴파일할 때만 필요한 정보이다.
자바스크립트로 컴파일 될 때 사라진다.
런타임때 접근할 수 있는 게 아니다.
하지만 클래스는 물리적으로 동작하는 메서드와 속성이 있으므로 컴파일되어도 자바스크립트에 남아있다.
따라서 앞 코드에서 FC 는 컴파일 되면 완전히 사라지는 정보라서 import type 구문을 사용한다.

함수 컴포넌트의 타입

앞서 함수 컴포넌트의 타입이 FunctionComponent<P> 라고 했다.
그런데 이름이 너무 길어서 리액트는 이를 짧게 줄인 FC 라는 이름의 타입을 제공한다.
결국 함수 컴포넌트의 타입은 FC<P> 타입이다.

FC<P> 에서 P 는 Property를 의미한다.

function 키워드 함수

type FunctionComponentProps = {
  href: string
  text: string
}
function FunctionComponent(props: FunctionComponentProps) {
  const {href, text} = props
  return (
    <ul>
      <li>
        <a href={href} target="_blank">
          <p>{text}</p>
        </a>
      </li>
    </ul>
  )
}
// 컴포넌트 호출
<FunctionComponent href="https://google.com" text="구글로 이동" />

화살표 함수

import type {FC} from 'react'

type FunctionComponentProps = {
  href: string
  text: string
}
const FunctionComponent: FC<FunctionComponentProps> = (props) => {
  const {href, text} = props
  return (
    <ul>
      <li>
        <a href={href} target="_blank">
          <p>{text}</p>
        </a>
      </li>
    </ul>
  )
}
// 컴포넌트 호출
<FunctionComponent href="https://google.com" text="구글로 이동" />
profile
프론트에_가까운_풀스택_개발자

0개의 댓글