From fbb3b7f05737f9571b04b0a8f4f15c0928de8545 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 7 Jul 2025 01:43:36 +0000 Subject: (대표님) 변경사항 20250707 10시 43분 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/data-table/data-table-grobal-filter.tsx | 1 - components/data-table/data-table-sort-list.tsx | 45 +++++++++++++++------- components/data-table/data-table.tsx | 40 ++++++++++++------- 3 files changed, 58 insertions(+), 28 deletions(-) (limited to 'components/data-table') diff --git a/components/data-table/data-table-grobal-filter.tsx b/components/data-table/data-table-grobal-filter.tsx index 240e9fa7..a1f0a6f3 100644 --- a/components/data-table/data-table-grobal-filter.tsx +++ b/components/data-table/data-table-grobal-filter.tsx @@ -17,7 +17,6 @@ export function DataTableGlobalFilter() { eq: (a, b) => a === b, clearOnDefault: true, shallow: false, - history: "replace" }) // Local tempValue to update instantly on user keystroke diff --git a/components/data-table/data-table-sort-list.tsx b/components/data-table/data-table-sort-list.tsx index c3c537ac..c752f2f4 100644 --- a/components/data-table/data-table-sort-list.tsx +++ b/components/data-table/data-table-sort-list.tsx @@ -54,19 +54,30 @@ interface DataTableSortListProps { shallow?: boolean } +let renderCount = 0; + export function DataTableSortList({ table, debounceMs, shallow, }: DataTableSortListProps) { + renderCount++; + const id = React.useId() const initialSorting = (table.initialState.sorting ?? []) as ExtendedSortingState + // ✅ 파서를 안정화 - 한 번만 생성되도록 수정 + const sortingParser = React.useMemo(() => { + // 첫 번째 행의 데이터를 안정적으로 가져오기 + const sampleData = table.getRowModel().rows[0]?.original; + return getSortingStateParser(sampleData); + }, []); // ✅ 빈 dependency - 한 번만 생성 + const [sorting, setSorting] = useQueryState( "sort", - getSortingStateParser(table.getRowModel().rows[0]?.original) + sortingParser .withDefault(initialSorting) .withOptions({ clearOnDefault: true, @@ -74,6 +85,10 @@ export function DataTableSortList({ }) ) + // ✅ debouncedSetSorting - 컴포넌트 최상위로 이동 + const debouncedSetSorting = useDebouncedCallback(setSorting, debounceMs); + + // ✅ uniqueSorting 메모이제이션 const uniqueSorting = React.useMemo( () => sorting.filter( @@ -82,8 +97,7 @@ export function DataTableSortList({ [sorting] ) - const debouncedSetSorting = useDebouncedCallback(setSorting, debounceMs) - + // ✅ sortableColumns 메모이제이션 const sortableColumns = React.useMemo( () => table @@ -100,7 +114,8 @@ export function DataTableSortList({ [sorting, table] ) - function addSort() { + // ✅ 함수들을 useCallback으로 메모이제이션 + const addSort = React.useCallback(() => { const firstAvailableColumn = sortableColumns.find( (column) => !sorting.some((s) => s.id === column.id) ) @@ -113,9 +128,9 @@ export function DataTableSortList({ desc: false, }, ]) - } + }, [sortableColumns, sorting, setSorting]); - function updateSort({ + const updateSort = React.useCallback(({ id, field, debounced = false, @@ -123,7 +138,7 @@ export function DataTableSortList({ id: string field: Partial> debounced?: boolean - }) { + }) => { const updateFunction = debounced ? debouncedSetSorting : setSorting updateFunction((prevSorting) => { @@ -134,13 +149,17 @@ export function DataTableSortList({ ) return updatedSorting }) - } + }, [debouncedSetSorting, setSorting]); - function removeSort(id: string) { + const removeSort = React.useCallback((id: string) => { void setSorting((prevSorting) => prevSorting.filter((item) => item.id !== id) ) - } + }, [setSorting]); + + const resetSorting = React.useCallback(() => { + setSorting(null); + }, [setSorting]); return ( ({ ) -} +} \ No newline at end of file diff --git a/components/data-table/data-table.tsx b/components/data-table/data-table.tsx index 64afcb7e..33fca5b8 100644 --- a/components/data-table/data-table.tsx +++ b/components/data-table/data-table.tsx @@ -25,6 +25,25 @@ interface DataTableProps extends React.HTMLAttributes { compact?: boolean // 컴팩트 모드 옵션 추가 } +// ✅ compactStyles를 정적으로 정의 (매번 새로 생성 방지) +const COMPACT_STYLES = { + row: "h-7", // 행 높이 축소 + cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정 + groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소 + emptyRow: "h-16", // 데이터 없을 때 행 높이 조정 + header: "py-1 px-2 text-sm", // 헤더 패딩 축소 + headerHeight: "h-8", // 헤더 높이 축소 +}; + +const NORMAL_STYLES = { + row: "", + cell: "", + groupRow: "bg-muted/20", + emptyRow: "h-24", + header: "", + headerHeight: "", +}; + /** * 멀티 그룹핑 + 그룹 토글 + 그룹 컬럼/헤더 숨김 + Indent + 리사이징 + 컴팩트 모드 */ @@ -41,18 +60,11 @@ export function DataTable({ useAutoSizeColumns(table, autoSizeColumns) - // 컴팩트 모드를 위한 클래스 정의 - const compactStyles = compact ? { - row: "h-7", // 행 높이 축소 - cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정 - groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소 - emptyRow: "h-16", // 데이터 없을 때 행 높이 조정 - } : { - row: "", - cell: "", - groupRow: "bg-muted/20", - emptyRow: "h-24", - } + // ✅ compactStyles를 useMemo로 메모이제이션 + const compactStyles = React.useMemo(() => + compact ? COMPACT_STYLES : NORMAL_STYLES, + [compact] + ); return (
@@ -62,7 +74,7 @@ export function DataTable({ {/* 테이블 헤더 */} {table.getHeaderGroups().map((headerGroup) => ( - + {headerGroup.headers.map((header) => { if (header.column.getIsGrouped()) { return null @@ -73,7 +85,7 @@ export function DataTable({ key={header.id} colSpan={header.colSpan} data-column-id={header.column.id} - className={compact ? "py-1 px-2 text-sm" : ""} + className={compactStyles.header} style={{ ...getCommonPinningStylesWithBorder({ column: header.column, -- cgit v1.2.3