Storm28
Storm28

Reputation: 69

How to scroll to top at each page change on Pagination component?

I would like to have an automatic scroll up when I change pages thanks to my Pagination component. It works great but I would like to add this feature. I have no idea how to do this..I tried with a tutorial that uses window but it doesn't worked because I've got no redirect, just a component divided into several pages (EventLists)... Thanks!! Here is my code :

PAGINATION COMPONENT

import PropTypes from 'prop-types';
// import { LinkContainer } from 'react-router-bootstrap';
import './pagination.scss';

const Pagination = ({ postsPerPage, totalPosts, paginate }) => {
  const pageNumbers = [];
  // eslint-disable-next-line no-plusplus
  for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
    pageNumbers.push(i);
  }
  return (
    <nav expand="lg" id="pagination-navbar">
      <ul className="pagination">
        {pageNumbers.map((number) => (
          <li key={number} className="page-item">
            <a
              style={{ cursor: 'pointer' }}
              onClick={() => paginate(number)}
              className="page-link"
            >{number}
            </a>
          </li>
        ))}
      </ul>
    </nav>
  );
};
Pagination.propTypes = {
  postsPerPage: PropTypes.number.isRequired,
  totalPosts: PropTypes.number.isRequired,
  paginate: PropTypes.func.isRequired,

};
export default Pagination;

FILE THAT USES Pagination

import { useState } from 'react';
import { useSelector } from 'react-redux';
// import react-Bootstrap's component(s)
import {
  Row,
} from 'react-bootstrap';
// import { useLocation } from 'react-router-dom';
import SearchBar from 'src/components/SearchBar';
import Pagination from 'src/components/Pagination';
import EventCard from '../EventCard';

import './eventsList.scss';

const EventsList = () => {
  // TODO code to retrieve the id with a useLocation (not found yet)
  // we use useLocation to retrieve the state of the route
  // in which we have stored genreId or regionId
  // if location is defined, take me its state
  // if the state is defined take me the region
  // console.log(location.state); => returns null
  const [currentPage, setCurrentPage] = useState(1);
  const [postsPerPage] = useState(9);

  const { eventsList } = useSelector((state) => state.events);
  // Get current posts
  const indexOfLastPost = currentPage * postsPerPage;
  const indexofFirstPost = indexOfLastPost - postsPerPage;
  const currentEvents = eventsList.slice(indexofFirstPost, indexOfLastPost);
  // Change page
  const paginate = (pageNumber) => setCurrentPage(pageNumber);
  return (
    <div>
      <SearchBar
      // we pass a string to change the title according to the page
      // we pass the length of the table to boost the results in the title
        results={eventsList.length}
        message="results"
        // genreId={genreId}
        // regionId={regionId}
      />
      <Row>
        {currentEvents.map((item) => (
          <EventCard key={item.id} {...item} />
        ))}
      </Row>
      <Pagination
        postsPerPage={postsPerPage}
        totalPosts={eventsList.length}
        paginate={paginate}

      />
    </div>
  );
};
export default EventsList;

Upvotes: 0

Views: 5567

Answers (2)

atazmin
atazmin

Reputation: 5707

This seem to work for me. MUI v5, React

...

const [page, setPage] = useState(props.props.pagination.page);

...

  useEffect(() => {
    window.scrollTo({
      top: 0,
      left: 0,
      behavior: 'smooth',
    });
  }, [page]);

...

  const handleChange = (event, value) => {
    setIsLoading(true);
    setPage(value);
  };

...

    <Pagination
      ...
      count={pageCount}
      page={page}
      onChange={handleChange} 
      ...       
    />

Upvotes: 1

codehero
codehero

Reputation: 509

You could make use of React Refs: https://reactjs.org/docs/refs-and-the-dom.html.

You create a ref, attach it to the element you want to scroll to, and scroll to that element when the page changes.

Something like:

const EventsList = () => {
  const pageTopRef = useRef(null);
  
  const paginate = (pageNumber) => {
    setCurrentPage(pageNumber);
    pageTopRef.current.scrollIntoView();
  };

  return (
    <div>
      ...
      <Row ref={pageTopRef}>
        {currentEvents.map((item) => (
          <EventCard key={item.id} {...item} />
        ))}
      </Row>
      ...
    </div>
  );
};

Upvotes: 1

Related Questions