49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
import { useCallback, useMemo } from "react";
|
|
import { useSearchParams } from "react-router-dom";
|
|
|
|
const PAGE_PARAM = "page";
|
|
|
|
export const useUrlPagination = (defaultPage = 1) => {
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
|
|
const currentPage = useMemo(() => {
|
|
const page = Number.parseInt(searchParams.get(PAGE_PARAM) ?? "", 10);
|
|
return Number.isFinite(page) && page > 0 ? page : defaultPage;
|
|
}, [searchParams, defaultPage]);
|
|
|
|
const handlePageChange = useCallback(
|
|
(page: number, options?: { replace?: boolean }) => {
|
|
setSearchParams(
|
|
(prev) => {
|
|
const next = new URLSearchParams(prev);
|
|
if (page <= defaultPage) {
|
|
next.delete(PAGE_PARAM);
|
|
} else {
|
|
next.set(PAGE_PARAM, page.toString());
|
|
}
|
|
return next;
|
|
},
|
|
{ replace: options?.replace ?? false },
|
|
);
|
|
},
|
|
[setSearchParams, defaultPage],
|
|
);
|
|
|
|
const resetPage = useCallback(() => {
|
|
setSearchParams(
|
|
(prev) => {
|
|
const next = new URLSearchParams(prev);
|
|
next.delete(PAGE_PARAM);
|
|
return next;
|
|
},
|
|
{ replace: true },
|
|
);
|
|
}, [setSearchParams]);
|
|
|
|
return {
|
|
currentPage,
|
|
handlePageChange,
|
|
resetPage,
|
|
};
|
|
};
|