커스텀 테이블 컴포넌트

테이블 UI는 빈번하게 사용되지만 구현 공수가 많이 드는 컴포넌트 중 하나다. 프로젝트에서 요구 기능이 제한적인 경우, 무거운 서드파티 라이브러리 대신 필요한 기능만 갖춘 커스텀 테이블 컴포넌트를 직접 만드는 것이 현실적인 선택이 될 수 있다.

최소 기능 정의가 출발점이다. 칼럼 데이터 키를 이용한 자동 컬럼 생성, 칼럼별 소팅(sorting) UI 및 이벤트 전달, 로딩 중/빈 데이터 상태 처리, 칼럼별 커스텀 마크업 삽입 정도를 갖추면 실무에서 충분히 재사용 가능하다.

타입 설계는 컴포넌트의 유연성을 결정한다. `tableConfig`에는 캡션, 테마, 커스텀 클래스, 컬럼 배열을 담고, 각 `Column`에는 `key`, `sortable`, `header` 렌더 함수, `cell` 렌더 함수, `align`, `size` 등을 정의한다. `header`와 `cell`을 `ReactNode`를 반환하는 함수로 설계하면 원시 데이터를 필요한 마크업으로 자유롭게 가공할 수 있다.

ColumnHelper(accessor) 패턴은 소팅 상태와 데이터 접근을 캡슐화한다. `columnHelper.accessor('key', config)` 형태로 컬럼을 선언하면, 외부에서는 키와 설정만 넘기고 소팅 가능 여부에 따른 헤더 렌더링 로직은 내부에서 처리된다. 다른 컬럼의 값도 `cell(value, item, index)` 형태로 접근 가능하도록 해두면 복합 데이터 표시가 가능하다.

소팅 상태 관리는 `reduce`로 초기값을 잡고 `useState`로 각 컬럼의 `'asc' | 'desc' | 'default'` 상태를 순환 토글한다. 소팅 불가능한 컬럼은 클릭 이벤트를 연결하지 않고, 소팅 아이콘은 `asc`/`desc` 상태일 때만 노출하는 방식이 깔끔하다.

로딩/빈 상태 분기는 컴포넌트의 완성도를 높인다. `isLoading`이 `true`면 로딩 영역을, `tableDatas.length === 0`이면 빈 상태 영역을 반환하고, 그 외에는 테이블 본체를 렌더링하는 순서로 처리한다.

핵심 내용

  • 최소 기능 범위 확정 후 타입부터 설계하는 순서가 효율적
  • `header`/`cell`을 함수 타입으로 정의하면 원시 데이터 → 마크업 변환이 자유로움
  • ColumnHelper accessor 패턴: 키와 컬럼 설정을 선언적으로 조합
  • 소팅 상태는 `default → asc → desc` 순환 토글로 관리
  • 로딩·빈 데이터 상태를 얼리 리턴으로 분기하면 코드 가독성 향상
  • Module SCSS + classnames 조합으로 조건부 클래스 처리

관련 개념

출처

최종 업데이트: 2026-04-08 | 출처 1개