Rev 3533 | Rev 3603 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import { useEffect, useState, useCallback, useMemo } from 'react';import { useFetch } from './useFetch';export function usePagination(url,{initialPage = 1,initialLimit = 10,initialParams = {},enableInfiniteScroll = false,resetOnUrlChange = true} = {}) {const [items, setItems] = useState([]);const [page, setPage] = useState(initialPage);const [totalPages, setTotalPages] = useState(0);const [totalItems, setTotalItems] = useState(0);const [limit, setLimit] = useState(initialLimit);const [params, setParams] = useState({ page, limit, ...initialParams });const { data, loading, error, refetch } = useFetch(url, {params});// Memoized pagination stateconst paginationState = useMemo(() => ({page,limit,totalPages,totalItems,hasMore: page < totalPages,hasPrevious: page > 1,isFirstPage: page === 1,isLastPage: page === totalPages}),[page, limit, totalPages, totalItems]);// Optimized page navigation functionsconst nextPage = useCallback(() => {if (paginationState.hasMore) {setPage((prevPage) => prevPage + 1);}}, [paginationState.hasMore]);const prevPage = useCallback(() => {if (paginationState.hasPrevious) {setPage((prevPage) => prevPage - 1);}}, [paginationState.hasPrevious]);const goToPage = useCallback((newPage) => {if (newPage >= 1 && newPage <= totalPages) {setPage(newPage);}},[totalPages]);const setPageLimit = useCallback((newLimit) => {if (newLimit > 0) {setLimit(newLimit);setPage(1);}}, []);const resetPagination = useCallback(() => {setPage(initialPage);setItems([]);setTotalPages(0);setTotalItems(0);}, [initialPage]);const updateParams = useCallback((newParams) => {setParams((prevParams) => ({ ...prevParams, ...newParams }));}, []);// Handle data updates with flexible structure supportuseEffect(() => {if (data) {let newItems = [];let pages = 0;let items = 0;// Handle different response structuresif (data?.current?.items) {// Structure: { current: { items: [] }, total: { pages: number, items: number } }newItems = data.current.items;pages = data.total?.pages || 0;items = data.total?.items || 0;} else if (data?.data && Array.isArray(data.data)) {// Structure: { data: [], pagination: { ... } }newItems = data.data;pages = data.pagination?.pageCount || data.pagination?.last || 0;items = data.pagination?.totalItemCount || 0;} else if (Array.isArray(data)) {// Structure: direct arraynewItems = data;pages = 1;items = data.length;} else if (data?.items && Array.isArray(data.items)) {// Structure: { items: [], pagination: { ... } }newItems = data.items;pages = data.pagination?.pageCount || data.pagination?.last || 0;items = data.pagination?.totalItemCount || 0;}setItems((prevItems) => {if (enableInfiniteScroll && page > 1) {// For infinite scroll, append new itemsreturn [...prevItems, ...newItems];} else {// For regular pagination, replace itemsreturn newItems;}});setTotalPages(pages);setTotalItems(items);}}, [data, page, enableInfiniteScroll]);// Update params when page or limit changesuseEffect(() => {setParams((prevParams) => ({...prevParams,page,limit}));}, [page, limit]);// Reset pagination when URL changes (if enabled)useEffect(() => {if (resetOnUrlChange) {resetPagination();}}, [url, resetOnUrlChange, resetPagination]);return {// Dataitems,...paginationState,// Loading and error statesloading,error,// ActionsnextPage,prevPage,goToPage,setPageLimit,resetPagination,updateParams,refetch};}