React Paginate: Not able to reset the selected page to 1 on changing the limit of items per page

4k Views Asked by At

I am using react paginate for the pagination. While changing the number of items displayed per page, I am not able to change the selected page to 1. After hitting the API, the active page doesn't move to '1' index. I have to click on it.

<ReactPaginate
    pageCount={parseInt(Math.ceil(pageCount / limit))}
    pageRange={3}
    marginPagesDisplayed={2}
    onPageChange={handlePageChange}
    containerClassName={
        "relative z-0 inline-flex rounded-md shadow-sm -space-x-px"
    }
    previousLinkClassName={
        "relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium "
    }
    breakClassName={
        "relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700"
    }
    nextLinkClassName={
        "relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium "
    }
    pageClassName={
        "bg-white border-gray-300 text-gray-500 hover:bg-gray-50 relative inline-flex items-center px-4 py-2 border text-sm font-medium"
    }
    disabledClassName={"text-gray-500 hover:bg-gray-50 cursor-none"}
    activeClassName={
        "z-10 bg-indigo-500 border-indigo-500 text-white relative inline-flex items-center px-4 py-2 border text-sm font-medium hover:text-indigo-500"
    }
    initialPage={0}
/>
2

There are 2 best solutions below

0
On

If you pass your data as a prop into a sub component, this is how you do it

You pass a state variable called results which is an array

<ListComponent
    results={results}
    resultsPerPage={16}
/>

Then you use that array inside the component to present data

import React, { PropsWithChildren, useEffect, useState } from "react";

import ReactPaginate from "react-paginate";

const ListItem = React.memo((props: PropsWithChildren<any>) => {
    return (
        <Row>
            {props.currentItems && props.currentItems.map((item) => (
                <div>
                    {item}
                </div>
            ))}
        </Row>
    );
})

const ListComponent = React.memo((props: PropsWithChildren<any>) => {
    const [currentItems, setCurrentItems] = useState(null);
    const [pageCount, setPageCount] = useState(0);
    const [currentPage, setCurrentPage] = useState(0);
    const [itemOffset, setItemOffset] = useState(0);

    // if results array change, go to the first page
    useEffect(() => {
        setItemOffset(0);

        setCurrentPage(0);
    }, [props.results]);

    useEffect(() => {
        const endOffset = itemOffset + props.resultsPerPage;

        setCurrentItems(props.results.slice(itemOffset, endOffset));
        setPageCount(Math.ceil(props.results.length / props.resultsPerPage));
    }, [props.results, props.resultsPerPage, itemOffset]);

    const handlePageClick = (event) => {
        const newOffset = event.selected * props.resultsPerPage % props.results.length;

        setItemOffset(newOffset);

        setCurrentPage(event.selected);
    };

    return (
        <>
            <ListItem currentItems={currentItems} />
            <div className="d-flex justify-content-center">
                <ReactPaginate
                    nextLabel=">"
                    onPageChange={handlePageClick}
                    pageRangeDisplayed={3}
                    marginPagesDisplayed={2}
                    pageCount={pageCount}
                    forcePage={currentPage}
                    previousLabel="<"
                    pageClassName="page-item"
                    pageLinkClassName="page-link"
                    previousClassName="page-item"
                    previousLinkClassName="page-link"
                    nextClassName="page-item"
                    nextLinkClassName="page-link"
                    breakLabel="..."
                    breakClassName="page-item"
                    breakLinkClassName="page-link"
                    containerClassName="pagination"
                    activeClassName="active"
                    renderOnZeroPageCount={null}
                />
            </div>
        </>
    );
});

export default ListComponent;

Whenever you pass a new results prop, we set itemOffset and currentPage as 0 to go to the first page.

0
On
const [currentPage, setCurrentPage] = useState(0);

const handlePageChange = ({ selected: selectedPage }) => {
    setCurrentPage(selectedPage);
};

<ReactPaginate
forcePage = {currentPage}/>

After hited api, set currentPage to 0.