본문으로 바로가기

React 컴포넌트에서 Generic 사용하기

만약 컴포넌트 개발이나 공용 유틸 함수를 개발하지 않는다면, 타입스크립트의 제네릭을 사용하지 않을 수도 있습니다.
이 글을 읽고 있다면 컴포넌트 개발에 어려움을 겪고 있을 가능성이 높습니다.
이제 리액트 컴포넌트에서 제네릭을 어떻게 활용할 수 있는지 간단히 살펴보겠습니다.

리액트 컴포넌트에서 제네릭 사용하는 방법

사용방법 1

const Component = (props:Props<T>) => {
  return <div></div>
}

위처럼 아주 간단하게 사용할 수 있습니다.
그러나 타입스크립트에게 T의 값에 대한 정보를 조금 더 제공해줄 수도 있습니다.

사용방법 2

const Component = <T extends string>(props: Props<T>) => {
  return <div></div>;
};

위처럼 작성하면 T의 값은 string에서 확장되었다는 것을 의미힙니다.

위 코드 2개정도면 리액트에서 제네릭을 사용하는 방법은 알았다고 할 수 있을 것 같습니다.

그럼 어떻게 활용할 수 있는 지 확인해봅시다.

테이블 구현

공용 컴포넌트 중 테이블 컴포넌트를 구현한다고 해보겠습니다.
예시 코드이므로 div만 사용하여 개발하였습니다.
그리고 완성된 코드를 보며 이해하는 것이 더 빠르기 때문에 코드를 확인해봅시다.

type Head<T extends string> = {
  key: T;
  label: string;
};

type Body<T extends string> = {
  [key in T]: any;
};

interface TableProps<T extends string> {
  head: Head<T>[];
  body: Body<T>[];
}

const Table = <T extends string>(
  props: TableProps<T>,
) => {
  const { head, body } = props;

  return (
    <div>
      {head.map(({ key, label }) => (
        <div key={key}>{label} </div>
      ))}
      {body.map((data, index) =>  (
          <React.Fragment key={index}>
            {head.map(el => {
              return <div key={el.key}>{data[el.key]}</div>;
            })}
          </React.Fragment>
        ))
      }
    </div>
  );
};

export default Table;

다양한 방법이 있겠지만 위와 같이 구현할 수 있을 것 같습니다. 간단하게 props를 설명하자면

  • head : 테이블의 label 값, 해당 label의 key 값의 배열
  • body : 테이블의 데이터 객체 배열

입니다.

type KeyValue = "name" | "age"

const head: Head<KeyValue>[]  = [
  { key: "name", label: "name" },
  { key: "age", label: "age" },
];

const body: Body<KeyValue>[] = [
  { name: "강호동", age: 10 },
  { name: "유재석", age: 15 },
];

const TestComponent = () => {
  return <Table<KeyValue> head={head} body={body} />;
};

위와 같이 실행할 수 있습니다.
이때 데이터 구조가 변경이 되는 경우 제네릭을 사용한 효과를 볼 수 있습니다.
기획에서 age를 삭제하고 phoneNumber, address를 추가해주세요 라고 한 경우 간단하게 처리가 가능합니다.

type KeyValue = "name" | "phoneNumber" | "address";

const head: Head<KeyValue>[] = [
  { key: "name", label: "name" },
  { key: "phoneNumber", label: "phone number" },
  { key: "address", label: "address" },
];

const body: Body<KeyValue>[] = [
  { name: "강호동", phoneNumber: "01011112222", address: "서울" },
  { name: "유재석", phoneNumber: "01033334444", address: "부산" },
];

const TestComponent = () => {
  return <Table<KeyValue> head={head} body={body} />;
};

위 예시를 통해 리액트에서 제네릭을 사용하는 방법을 알아보았습니다.
제네릭을 사용할 수 있는 대표적인 컴포넌트는 Select 입니다.
시간이 되실 때 연습으로 Select 컴포넌트를 구현해보시면 좋을 것 같습니다.

반응형