summaryrefslogtreecommitdiff
path: root/hooks/use-data-table.ts
diff options
context:
space:
mode:
Diffstat (limited to 'hooks/use-data-table.ts')
-rw-r--r--hooks/use-data-table.ts74
1 files changed, 38 insertions, 36 deletions
diff --git a/hooks/use-data-table.ts b/hooks/use-data-table.ts
index a93b25c0..1cbae9de 100644
--- a/hooks/use-data-table.ts
+++ b/hooks/use-data-table.ts
@@ -40,6 +40,7 @@ import useSWRInfinite from "swr/infinite";
import { getSortingStateParser } from "@/lib/parsers";
import { useDebouncedCallback } from "@/hooks/use-debounced-callback";
import isEqual from "fast-deep-equal";
+import deepEqual from "fast-deep-equal";
// ───────────────────────────────────────────────────────────────────────
// 무한 스크롤 관련 상수 및 타입
@@ -457,45 +458,46 @@ export function useDataTable<TData>({
}
}, [filterFields, enableAdvancedFilter])
- const onColumnFiltersChange = React.useCallback(
- (updaterOrValue: Updater<ColumnFiltersState>) => {
- if (enableAdvancedFilter) return
- setColumnFilters((prev) => {
- const next =
- typeof updaterOrValue === "function"
- ? updaterOrValue(prev)
- : updaterOrValue
-
- const filterUpdates = next.reduce<
- Record<string, string | string[] | null>
- >((acc, filter) => {
- if (searchableColumns.find((col) => col.id === filter.id)) {
- acc[filter.id] = filter.value as string
- } else if (filterableColumns.find((col) => col.id === filter.id)) {
- acc[filter.id] = filter.value as string[]
- }
- return acc
- }, {})
-
- prev.forEach((prevFilter) => {
- if (!next.some((filter) => filter.id === prevFilter.id)) {
- filterUpdates[prevFilter.id] = null
- }
+// -------- column-filters 변경 핸들러 (루프 차단 버전) --------
+const onColumnFiltersChange = React.useCallback(
+ (updater: Updater<ColumnFiltersState>) => {
+ setColumnFilters(prev => {
+ const next =
+ typeof updater === "function" ? updater(prev) : updater
+
+ /* 변동이 없으면 바로 종료 */
+ if (deepEqual(prev, next)) return prev
+
+ /* ---------- URL 동기화: 고급필터 OFF 때만 ---------- */
+ if (!enableAdvancedFilter) {
+ const updates: Record<string, string | string[] | null> = {}
+
+ next.forEach(f => {
+ if (searchableColumns.some(c => c.id === f.id))
+ updates[f.id] = f.value as string
+ else if (filterableColumns.some(c => c.id === f.id))
+ updates[f.id] = f.value as string[]
+ })
+ prev.forEach(pf => {
+ if (!next.some(nf => nf.id === pf.id)) updates[pf.id] = null
})
void setPage(1)
- debouncedSetFilterValues(filterUpdates)
- return next
- })
- },
- [
- debouncedSetFilterValues,
- enableAdvancedFilter,
- filterableColumns,
- searchableColumns,
- setPage,
- ]
- )
+ debouncedSetFilterValues(updates)
+ }
+
+ return next // ★ 항상 state 를 반영
+ })
+ },
+ [
+ enableAdvancedFilter,
+ searchableColumns,
+ filterableColumns,
+ deepEqual, // fast-deep-equal
+ debouncedSetFilterValues,
+ setPage,
+ ]
+)
// -------- TanStack Table 인스턴스 생성 --------
const table = useReactTable({