TanStack React Table v8 - 컬럼 필터

정형진·2022년 8월 25일
3

컬럼 필터 (Column Filter)

react-table의 필터는 크게 다음의 두 가지 종류로 나뉩니다. 본 문서에서는 Column Filter를 위주로 다룰 예정입니다.

  1. Column Filters : 한 컬럼의 accessor 값에만 적용되는 필터. state.columnFilterscolumnId와 함께 array 타입으로 저장된다.
  2. Global Filters : 전체 컬럼의 accessor 값에 적용되는 필터. state.globalFiltersany 타입으로 저장된다. (대부분 string)

Column Defs 설정

enableColumnFilter

const columns = [
  columnHelper.accessor("name", {
    header: "이름",
    enableColumnFilter: true,
  }),
  columnHelper.accessor("phone", {
    header: "휴대폰",
    enableColumnFilter: false,
  }),
  /* ... */
]

정렬과 마찬가지로 enableColumnFilter 옵션을 통해 컬럼에 컬럼 필터 기능을 사용할지 사용하지 않을지를 선택할 수 있습니다. 마찬가지로 기본값이 true입니다.

filterFn

const columns = [
  columnHelper.accessor("name", {
    header: "이름",
    filterFn: "equalsString",
  }),
]

filterFn 옵션을 통해 필터 함수를 지정할 수 있습니다. react-table에서 제공하는 10개의 기본 필터링 함수 이름 중 하나를 스트링 형태로 넘기거나, 커스텀 필터를 작성하여 넘기는 것도 가능합니다.

커스텀 필터를 작성하는 방법에 대해서는 별도의 포스팅으로 정리할 예정입니다. 또는 공식 문서에도 커스텀 필터를 작성하는 방법에 대해 소개하는 부분이 있으므로 참고 바랍니다.

Table 설정

getFilteredRowModel, getFacetedUniqueValues

import {
  getCoreRowModel,
  getFilteredRowModel,
  getFacetedUniqueValues
  useReactTable,
} from "@tanstack/react-table";
/* ... */
const table = useReactTable({
  data,
  columns,
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(),
  getFacetedUniqueValues: getFacetedUniqueValues(),
})

getFilteredRowModel 함수를 임포트하여 테이블 선언 시 함께 보내주어야 필터링된 Row Model를 출력할 수 있습니다. getFacetedUniqueValues는 각 컬럼 안에 있는 unique한 value들을 종류별로 출력해주는 함수입니다. 컬럼별로 필터 목록을 출력할 때 사용합니다.

TanStack Table v8 Documents | getFilteredRowModel
TanStack Table v8 Documents | getFactedUniqueValues

필터링 함수 적용

getFacetedUniqueValues

// App.js
<thead>
  {table.getHeaderGroups().map((headerGroup) => (
    <tr key={headerGroup.id}>
      {headerGroup.headers.map((header) => (
        <TableHeader header={header} key={header.id} />
      ))}
    </tr>
  ))}
</thead>
// TableHeader.jsx
function TableHeader({ header }) {
  const sortedUniqueValues = useMemo(
    () => Array.from(header.column.getFacetedUniqueValues().keys()).sort(),
    [header.column]
  );

  return (
    <th
      key={header.id}
      style={{
        width: header.getSize(),
        cursor: header.column.getCanSort() ? "pointer" : "default",
      }}
      onClick={header.column.getToggleSortingHandler()}
    >
      {header.isPlaceholder
        ? null
        : flexRender(header.column.columnDef.header, header.getContext())}
      {
        {
          asc: <FaSortUp />,
          desc: <FaSortDown />,
        }[header.column.getIsSorted()]
      }
      {header.column.getCanSort() && !header.column.getIsSorted() ? (
        <FaSort />
      ) : null}
    </th>
  );
}

컬럼별 unique value를 추출하기 위해 먼저 헤더 컴포넌트를 분리해줍니다. getFacetedUniqueValues 함수를 이용하면 정말 간단하게 각 컬럼의 unique value들을 배열로 출력할 수 있습니다.

getCanFilter, setFilterValue

// TableHeader.jsx
const onFilterChange = (value) => {
  if (value === "null") {
    header.column.setFilterValue(null);
  } else {
    header.column.setFilterValue(value);
  }
};
// TableHeader.jsx
{header.column.getCanFilter() ? (
  <select
    onChange={({ currentTarget: { value } }) => onFilterChange(value)}
  >
    <option value="null">선택 안함</option>
    {sortedUniqueValues.map((value) => (
      <option key={value}>{value}</option>
    ))}
  </select>
) : null}

getCanFilter는 해당 컬럼이 필터링 가능한 컬럼인지 아닌지를 반환하는 함수로, 여기서는 필터링이 불가능한 컬럼에는 필터링 엘리먼트를 표시하지 않기 위해 사용했습니다. setFilterValue는 필터값을 지정해주는 함수로, 다양한 방식으로 필터값을 지정해줄 수 있습니다. 예제에서는 선택지 국룰인 select 태그를 이용하여 unique value 중 하나를 filterValue로 지정할 수 있는 로직을 만들어보았습니다. 이로써 간단하게 필터 기능까지 완성되었습니다!

TanStack Table v8 Documents | Filters

profile
사실 나도 잘 모름

0개의 댓글