Generic 컴포넌트 사용 예시(테이블)

  • 상황에 따라 컴포넌트의 props 타입이 변경되도록 하기위한 테크닉입니다.
  • 핵심 데이터에 해당되는 prop을 Generic화 하여, 그에 맞는 타입을 구성하면 값을 대입할 시 그에 맞는 타입으로 컴포넌트 props가 추론됩니다.
import { ReactNode } from 'react'

type HeadCell<ListItem> = {
  id: Extract<keyof ListItem, string>
  label: string
}

type Props<ListItem> = {
  headCells: HeadCell<ListItem>[]
  items: ListItem[]
  renderItem: (item: ListItem) => ReactNode
  page?: number
  pageSize?: number
}

const Table = <ListItem extends { id: string | number }>({
  headCells,
  items,
  renderItem,
  page = 0,
  pageSize = 0,
}: Props<ListItem>) => {
  return (
    <div className="overflow-x-auto">
      <table className="table">
        {/* head */}
        <thead>
          <tr>
            <th></th>
            {headCells.map((headCell) => (
              <th key={headCell.id}>{headCell.label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {items.map((item, idx) => (
            <tr key={item.id}>
              <th>{(page - 1) * pageSize + (idx + 1)}</th>
              {renderItem(item)}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}
export default Table