David Jay
David Jay

Reputation: 353

How to make a button pagination works in React

I have an array of 12 objects of a list of movies and i want to create pagination for them using React paginate by displaying 4 items for each page, I already display the items on the UI but the numbers of pages didn't work even when I click on the Next button.

it is my first experience with pagination in react.

import './App.css';
import React,{useState} from 'react';
import MoviesData  from './components/Data/MoviesData';
import ReactPaginate from 'react-paginate';

function App() {
  const [categories, setCategories] = useState(allCategories);
  const [moviesList, setMoviesList] = useState(MoviesData.slice(0, 4));
  const [pageNumber, setPageNumber] = useState(0);



  const moviePerPage = 4;
  //to determinate how many pages we going to have
  const pageCount = Math.ceil(moviesList.length / moviePerPage);

  const changePage = ({ selected }) => {
    setPageNumber(selected);
  };

 
  return (
    <main>

      <MoviesCards moviesList ={moviesList} removeMovie={removeMovie}  />
      <ReactPaginate
        previousLabel={"Previous"}
        nextLabel={"Next"}
        pageCount={pageCount}
        onPageChange={changePage}
        containerClassName={"paginationBttns"}
        previousLinkClassName={"previousBttn"}
        nextLinkClassName={"nextBttn"}
        disabledClassName={"paginationDisabled"}
        activeClassName={"paginationActive"}
      />
    </main>
    
  )
}

export default App;

This component where i display my items :

import React from 'react';
import SingleMovieCard from '../SingleMovieCard/SingleMovieCard';

const MoviesCards = ({moviesList}) => {
    return (
        <section>

        <div className="title">
            <h2>Welcome to the box office</h2>
        </div>
        
        <div >
        {moviesList.map((singleMovie)=>  {
        return(
            <SingleMovieCard singleMovie={singleMovie}
                             key={singleMovie.id}
                             removeMovie={removeMovie} />
        )
        })}

        </div>
        </section>
        
    )
}


export default MoviesCards;

Upvotes: 0

Views: 795

Answers (1)

Vinicius Katata
Vinicius Katata

Reputation: 1051

There is some problems. I will list it here:

const pageCount = Math.ceil(moviesList.length / moviePerPage);

should be:

const pageCount = Math.ceil(MoviesData.length / moviePerPage);

That's because your page count is relative to whole movie count not only the page count, which is your state storing

Another problem is with your page management, the first is ok, however every time you change your page you need to set it with the new list of movies. That means you need an useEffect to track changes in pageNumber and then set your moviesList, something like this:

useEffect(() => {
  setMoviesList(MoviesData.slice(pageNumber * 4, (pageNumber + 1) * 4));
}, [pageNumber]);

I've done a simple case:

import React, { useEffect, useState } from "react";
import ReactPaginate from "react-paginate";

const MoviesData = [
  { title: "Foo", category: "horror" },
  { title: "Foo1", category: "horror" },
  { title: "Foo2", category: "horror" },
  { title: "Foo3", category: "horror" },
  { title: "Bar", category: "horror" },
  { title: "Bar1", category: "horror" },
  { title: "Bar2", category: "horror" },
  { title: "Bar3", category: "horror" }
];

const SingleMovieCard = ({ singleMovie }) => {
  return <div>{singleMovie.title}</div>;
};

const MoviesCards = ({ moviesList }) => {
  return (
    <section>
      <div className="title">
        <h2>Welcome to the box office</h2>
      </div>

      <div>
        {moviesList.map((singleMovie) => {
          return (
            <SingleMovieCard singleMovie={singleMovie} key={singleMovie.id} />
          );
        })}
      </div>
    </section>
  );
};

function App() {
  const [pageNumber, setPageNumber] = useState(0);
  const [moviesList, setMoviesList] = useState(MoviesData.slice(0, 4));

  const moviePerPage = 4;
  const pageCount = Math.ceil(MoviesData.length / moviePerPage);

  useEffect(() => {
    setMoviesList(MoviesData.slice(pageNumber * 4, (pageNumber + 1) * 4));
  }, [pageNumber]);

  const changePage = ({ selected }) => {
    console.log(selected);
    setPageNumber(selected);
  };

  return (
    <main>
      <MoviesCards moviesList={moviesList} />
      <ReactPaginate
        previousLabel={"Previous"}
        nextLabel={"Next"}
        pageCount={pageCount}
        onPageChange={changePage}
        containerClassName={"paginationBttns"}
        previousLinkClassName={"previousBttn"}
        nextLinkClassName={"nextBttn"}
        disabledClassName={"paginationDisabled"}
        activeClassName={"paginationActive"}
      />
    </main>
  );
}

export default App;

Upvotes: 1

Related Questions