diff --git a/frontend/src/hooks/usePaginationParams.ts b/frontend/src/hooks/usePaginationParams.ts index 346022cd..3a643bac 100644 --- a/frontend/src/hooks/usePaginationParams.ts +++ b/frontend/src/hooks/usePaginationParams.ts @@ -1,5 +1,5 @@ import { useSearchParams } from 'react-router-dom' -import { useCallback, useMemo } from 'react' +import { useCallback, useMemo, useRef } from 'react' type PageSize = number | 'all' @@ -8,8 +8,15 @@ interface UsePaginationParamsOptions { allowedPageSizes?: PageSize[] } +const DEFAULT_ALLOWED: PageSize[] = [10, 25, 50, 'all'] + export function usePaginationParams(options: UsePaginationParamsOptions = {}) { - const { defaultPageSize = 10, allowedPageSizes = [10, 25, 50, 'all'] } = options + const { defaultPageSize = 10, allowedPageSizes = DEFAULT_ALLOWED } = options + + // Stabilize the array reference to avoid re-render loops + const allowedRef = useRef(allowedPageSizes) + allowedRef.current = allowedPageSizes + const [searchParams, setSearchParams] = useSearchParams() const page = useMemo(() => { @@ -20,11 +27,11 @@ export function usePaginationParams(options: UsePaginationParamsOptions = {}) { const pageSize = useMemo((): PageSize => { const raw = searchParams.get('size') - if (raw === 'all' && allowedPageSizes.includes('all')) return 'all' + if (raw === 'all' && allowedRef.current.includes('all')) return 'all' const n = raw ? parseInt(raw, 10) : defaultPageSize - if (Number.isFinite(n) && allowedPageSizes.includes(n)) return n + if (Number.isFinite(n) && allowedRef.current.includes(n)) return n return defaultPageSize - }, [searchParams, defaultPageSize, allowedPageSizes]) + }, [searchParams, defaultPageSize]) const setPage = useCallback( (newPage: number) => {