[React] 리액트 & Next.JS

컴포넌트의 타입을 도와주는 ComponentProps를 알아보자.

OnceBH 2023. 8. 20. 00:48
반응형

컴포넌트의 타입을 도와주는 ComponentProps를 알아보자.

 

안녕하세요.

오늘은 타입스크립트로 리액트라이브러리를 사용할 때

컴포넌트가 사용하는 Props의 타입을 쉽게 가져올 수 있는 ComponentProps에 관해서 알아보겠습니다.

 

  1. Props의 타입을 재사용하는 방법?
  2. ComponentProps란?
  3. 마치며.

 

1. Props의 타입을 재사용하는 방법?

리액트로 개발을 하다 보면 빈번하게 새로운 타입을 만들고 사용하며 import 하고 export 합니다.

그리고 이는 새로운 컴포넌트를 만들 때도 동일합니다.

아래의 예시를 잠깐 보겠습니다.

import { FC } from 'react';

export type TestComponentPropsType = {
  testId: number;
  testName: string;
  isSuccess: boolean;
};

const TestComponent: FC<TestComponentPropsType> = ({
  testId,
  testName,
  isSuccess,
}) => {
  return (
    <div>
      <p>{testId}</p>
      <p>{testName}</p>
      {isSuccess ? <p>success</p> : <p>fail</p>}
    </div>
  );
};

export default TestComponent;

이렇게 기본적인 TestComponent라는 이름의 컴포넌트를 생성하였고, Props에 필요한 타입까지 지정했습니다.

자, 그럼 만약 어떠한 다른 컴포넌트에 TestComponent라는 컴포넌트와 그의 타입이 필요하다면 어떻게 할까요?

아마 아래의 예시와 같이 import 하는 것이 가장 보편적인 방법이지 않을까 싶습니다.

import TestComponent, { type TestComponentPropsType } from '../testComponent';

혹은

import TestComponent, { TestComponentPropsType } from '../testComponent';

하지만 이렇게 꼭 컴포넌트와 타입을 각각 일일이 따로 import 할 필요가 있을까요?

그냥 TestComponent만 import 하고 그에 상응하는 타입을 사용할 수는 없을까요?

이럴 때 필요한 게 바로 ComponentProps입니다.

 

 

2. ComponentProps란?

 

ComponentProps란 이미 리액트가 내장하고 있는 기능 중 하나입니다.

ComponentProps를 사용하기 위해서 먼저 import 하는 방법을 보겠습니다.

아래의 코드를 사용하여 ComponentProps를 import 합니다.

import { ComponentProps } from 'react';

 

자, ComponentProps는 기본적으로 우리가 생성한 컴포넌트뿐만 아니라 DOM-Elements 즉 button, input 등등의 타입까지 가져올 수 있습니다.

예시를 보겠습니다.

type ButtonType = ComponentProps<'button'>;

이렇게 사용하여 button의 타입을 사용할 수 있습니다.

ButtonType위에 마우스를 올리면 아래의 타입이 지정되어 있음을 알 수 있습니다.

type ButtonType = ClassAttributes<HTMLButtonElement> & ButtonHTMLAttributes<HTMLButtonElement>

그리고 아래와 같이 새로운 button 컴포넌트를 만들 때 사용할 수 있습니다.

import { Container } from '@mui/material';
import { ComponentProps } from 'react';

type ButtonType = ComponentProps<'button'>;

const SOmething = ({ onClick, test1 }: ButtonType) => {
  return <button onClick={onClick}>Click!</button>;
};

const TestPage = () => {
  return (
    <Container>
      <SOmething onClick={() => console.log('hello')} />
    </Container>
  );
};

export default TestPage;

 자 위의 코드의 경우 Click!이라는 버튼을 누를 경우 hello라는 문자가 콘솔에 표시될 것입니다.

당연히 이보다 더 활용성 높게 사용 할 수 있으나 가벼운 예시를 위해서 아주 간단하게 만들어 보았습니다.

 

자 그럼 본격적으로 HTML Element가 아닌 Component의 타입을 가져와 보도록 하겠습니다.

우리가 생성한 컴포넌트의 타입을 ComponentProps를 이용하여 가져오기 위해선 typeof라는 키워드가 사용되어야 합니다.

아래의 예시를 보겠습니다.

type TestComponentType = ComponentProps<typeof TestComponent>;

자 이제 마우스를 TestComponentType이라는 타입 위에 놓으면 이러한 타입임을 확인할 수 있습니다.

type TestComponentType = {
    testId: number;
    testName: string;
    isSuccess: boolean;
}

이는 우리가 위에 작성했던 타입 TestComponentPropsType와 동일한 타입을 가지고 있음을 알 수 있습니다.

아래의 예시를 보겠습니다.

import { Container } from '@mui/material';
import { ComponentProps, FC } from 'react';
import TestComponent from '../testComponent';

type TestComponentType = ComponentProps<typeof TestComponent>;

const Test2Component: FC<TestComponentType> = ({
  testId,
  testName,
  isSuccess,
}) => {
  return (
    <div>
      <p>{testId}</p>
      <p>{testName}</p>
      {isSuccess ? <p>success again</p> : <p>fail again</p>}
    </div>
  );
};

const TestPage = () => {
  return (
    <Container>
      <TestComponent testId={1} testName='test1' isSuccess />
      <Test2Component testId={2} testName='test2' isSuccess={false} />
    </Container>
  );
};

export default TestPage;

자, TestComponent라는 컴포넌트의 Props에 사용되는 타입을 가져와 Test2 Component라는 컴포넌트를 만들고 같은 타입을 사용하였습니다. 또한 타입을 변경하거나 확장하는 것도 가능합니다.

아래의 예시를 간단히 보겠습니다.

type TestComponentType = ComponentProps<typeof TestComponent> & {
  testInformation?: string;
};

type TestComponentType = Omit<ComponentProps<typeof TestComponent>, 'testId'>;

이렇게 또 다른 타입을 확장시키거나 불필요한 타입을 제거할  수 있습니다.

첫 번째 타입의 경우 기존 타입에 testInformation이라는 타입을 확장시킨 것이고,

아래의 Omit을 사용한 타입은 기존 타입에서 testId라는 타입을 제거한 것입니다.

 

3. 마치며.

개발을 하다 보면 항상 조금 더 편하고 쉬운 길이 있는 것 같습니다.

그래서 개발자는 그 누구보다 게을러질 수 있도록 노력해야 하는 것 같습니다.

오늘도 제 글이 조금이나마 도움이 될 수 있으면 좋겠습니다!

 

완벽한 준비란 없다, 완벽한 준비란 영원히 시작하지 않는 것과 같다.

Es gibt keine perfekte Vorbereitung.

Perfekte Vorbereitung ist das Gleiche, wie nie anzufangen.

반응형